对于复杂的形状使用 SVG 而不是 CSS:
正如我在评论中提到的,请不要使用 CSS 来创建如此复杂的形状。 SVG 是处理此类复杂内容的推荐工具。 SVG 易于创建和维护,并且默认情况下它们也是响应式(可缩放)的,因此它具有很多优点。
创建 sigmoid 形状:
使用 SVG 本身创建 sigmoid 曲线形状非常简单,只需要一个路径元素:
-
M0,750
将假想笔移动到靠近 SVG 元素左下角的位置(坐标设置为略低于 SVG 高度,以便底部有一个间隙,阴影可见)。
-
L250,750
产生一个水平的L从点 (0,768) 到 (250,768)
-
C650,730 500,154 1024,154
创建实际曲线。这里前两个坐标是曲线的控制点((650,730),(500,154)),第三个坐标是终点(1024,154)。可以通过修改控制点来调整曲线的曲率。
-
L1024,0 0,0 0,750
是为了完成形状。形状需要完整才能填充。
body {
margin: 0;
}
svg {
width: 100%;
height: 100vh;
}
<svg viewBox='0 0 1024 768' preserveAspectRatio='none'>
<!-- For the shadow -->
<defs>
<filter id="dropShadow">
<feGaussianBlur in="SourceAlpha" stdDeviation="6" />
<feOffset dx="3" dy="3" result="offsetBlur" />
<feFlood flood-color="#AAA" flood-opacity="1" result="offsetColor" />
<feComposite in="offsetColor" in2="offsetBlur" operator="in" result="offsetBlur" />
<feMerge>
<feMergeNode />
<feMergeNode in="SourceGraphic" />
</feMerge>
</filter>
</defs>
<!-- End of shadow -->
<!-- For filling the top-left with pattern -->
<pattern id='dots' patternUnits='userSpaceOnUse' width='25' height='25'>
<polygon points='0,0 0,25 25,25 25,0' fill='yellowgreen' />
<circle cx='12.5' cy='12.5' r='4' fill='rebeccapurple' />
</pattern>
<!-- End of pattern -->
<!-- Actual sigmoid curve -->
<path d='M0,750 L250,750 C650,730 500,154 1024,154 L1024,0 0,0 0,750' fill='url(#dots)' filter='url(#dropShadow)' />
</svg>
将图案应用到形状:
在上面的演示中,我使用以下命令创建了一个圆点图案polygon
and circle
elements 但并不强制在 SVG 本身中创建它,我们也可以使用image
元素并用图像图案填充形状。
如果您想将背景图像(图案)更改为您选择的其他图像,只需在xlink:href
的属性image
标签如下面的代码片段所示。根据您的需求和形象,您可能需要更改height
and width
of pattern
and image
.
<pattern id='dots' patternUnits='userSpaceOnUse' width='25' height='25'>
<image xlink:href='https://yourwebsite.com/yourpath' x='0' y='0' width='15' height='15' />
</pattern>
body {
margin: 0;
}
svg {
width: 100%;
height: 100vh;
}
<svg viewBox='0 0 1024 768' preserveAspectRatio='none'>
<defs>
<filter id="dropShadow">
<feGaussianBlur in="SourceAlpha" stdDeviation="6" />
<feOffset dx="3" dy="3" result="offsetBlur" />
<feFlood flood-color="#AAA" flood-opacity="1" result="offsetColor" />
<feComposite in="offsetColor" in2="offsetBlur" operator="in" result="offsetBlur" />
<feMerge>
<feMergeNode />
<feMergeNode in="SourceGraphic" />
</feMerge>
</filter>
<pattern id='dots' patternUnits='userSpaceOnUse' width='36.6' height='46'>
<image xlink:href='http://famok.com/wp-content/uploads/2016/10/WhiteOnWhite.jpg' x='0' y='0' width='36.6' height='46' />
</pattern>
</defs>
<path d='M0,750 L250,750 C650,730 500,154 1024,154 L1024,0 0,0 0,750' fill='url(#dots)' filter='url(#dropShadow)' />
</svg>
Note: The image used in the above demo is not my own. It was taken from the internet.
影子:
阴影效果是使用SVG创建的filter
元素连同feGaussianBlur
, feOffset
和feMerge
元素。这feGaussianBlur元素通过指定的标准偏差值和feOffset将结果图像偏移dx
, dy
价值观。原始图像和模糊图像是使用合并的feMerge. The feFlood和feComposite添加它们是为了防止您想给阴影赋予不同的颜色。颜色可以使用指定flood-color
and flood-opacity
属性。 (改变SVG投影颜色的方法取自这个答案作者:乔·W.)
添加文本:
现在这是整个事情中真正棘手的一点。如果您需要仅将文本放置在页面的纯色区域上,那么您需要仔细使用定位属性。如果文本很小或者只有一行文本那么我们可以使用 SVGtext
元素本身就像我之前链接的演示中一样。如果不是,那么您必须确保文本的容器框不会重叠到 sigmoid 形状的区域上。
body {
margin: 0;
}
div.container {
position: relative;
width: 100%;
height: 100vh;
}
svg {
position: absolute;
top: 0px;
left: 0px;
height: 100%;
width: 100%;
}
.container div {
position: absolute;
top: 50%;
right: 0px;
height: 30vh;
width: 33.33%;
font-size: 20px;
}
<div class='container'>
<svg viewBox='0 0 1024 768' preserveAspectRatio='none'>
<defs>
<!-- For the shadow -->
<filter id="dropShadow">
<feGaussianBlur in="SourceAlpha" stdDeviation="6" />
<feOffset dx="3" dy="3" result="offsetBlur" />
<feFlood flood-color="#AAA" flood-opacity="1" result="offsetColor" />
<feComposite in="offsetColor" in2="offsetBlur" operator="in" result="offsetBlur" />
<feMerge>
<feMergeNode />
<feMergeNode in="SourceGraphic" />
</feMerge>
</filter>
<!-- End of shadow -->
<!-- For filling the top-left with pattern -->
<pattern id='dots' patternUnits='userSpaceOnUse' width='25' height='25'>
<polygon points='0,0 0,25 25,25 25,0' fill='yellowgreen' />
<circle cx='12.5' cy='12.5' r='4' fill='rebeccapurple' />
</pattern>
<!-- End of pattern -->
</defs>
<!-- Actual sigmoid curve -->
<path d='M0,750 L250,750 C650,730 500,154 1024,154 L1024,0 0,0 0,750' fill='url(#dots)' filter='url(#dropShadow)' />
</svg>
<div>Hello! Here is some text that is placed on the solid colored area of the page.</div>
</div>
我们可以尝试使用CSSshape-outside
财产但浏览器对此的支持很差眼下。这里有一个demo使用这个shape-outside
财产。无法在现场托管它,因为它需要创建单独的 SVG 文件。该演示是 中提供的演示的改编版本W3C CSS 形状规范.
替代方法:(将模式应用到容器而不是 SVG)
由于您不希望图像被压扁或拉伸,因此另一种方法是执行以下操作:
- 创建 SVG 形状,使其仅是纯色部分(而不是图案区域)
- 将图案应用到
div.container
然后将 SVG 绝对放置在元素的顶部。 SVG 形状(具有白色填充)将防止图案在另一侧可见。
- 将 SVG 上的阴影从正常投影更改为嵌入阴影。 (Inset Shadow的代码完全取自here.
body {
margin: 0;
}
div.container {
position: relative;
background: white url(http://famok.com/wp-content/uploads/2016/10/WhiteOnWhite.jpg) top left / 26px 32px repeat;
width: 100%;
height: 100vh;
}
svg {
position: absolute;
top: 0px;
left: 0px;
height: 100%;
width: 100%;
}
.container div {
position: absolute;
top: 50%;
right: 0px;
height: 30vh;
width: 33.33%;
font-size: 20px;
}
<div class='container'>
<svg viewBox='0 0 1024 768' preserveAspectRatio='none'>
<defs>
<filter id="dropShadow" x="-50%" y="-50%" width="200%" height="200%">
<feComponentTransfer in=SourceAlpha>
<feFuncA type="table" tableValues="1 0" />
</feComponentTransfer>
<feGaussianBlur stdDeviation="6" />
<feOffset dx="2" dy="2" result="offsetblur" />
<feFlood flood-color="#AAA" result="color" />
<feComposite in2="offsetblur" operator="in" />
<feComposite in2="SourceAlpha" operator="in" />
<feMerge>
<feMergeNode in="SourceGraphic" />
<feMergeNode />
</feMerge>
</filter>
</defs>
<path d='M0,750 L250,750 C650,730 500,154 1024,154 L1024,768 0,768 0,750' fill='white' filter='url(#dropShadow)' />
</svg>
<div>Hello! Here is some text that is placed on the solid colored area of the page.</div>
</div>
Here is 笨蛋演示对于替代方法。这比前一个复杂一点,因为这里我们需要一个 SVG 来生成纯色区域(用作img
)和另一个 SVG,它是要使用的相反(图案区域)shape-outside
.