CSS 的 S 形曲线形状
Sigmoid Curve Shape with CSS
我想为全屏布局创建一个类似 sigmoid curve 的形状,在一侧显示装饰图案背景,在另一侧显示纯色背景,以便文本显示放在它上面。
目标是拥有一个全屏页面,其左上角填充有图案,页面的其余部分只有白色背景。
JSFiddle:Unfinished sigmoid curve
#container {
padding-top: 10%;
padding-bottom: 10%;
background: white url(http://famok.com/wp-content/uploads/2016/10/WhiteOnWhite.jpg) top left / 26px 32px repeat;
width: 100%;
height: 100%;
overflow: hidden;
}
#parallelogram {
margin-left: 35%;
width: 100%;
height: 900px;
-webkit-transform: skew(-15deg);
-moz-transform: skew(-15deg);
-o-transform: skew(-15deg);
transform: skew(-15deg);
background: white;
-moz-border-radius: 100px;
-webkit-border-radius: 100px;
border-radius: 100px;
-moz-box-shadow: inset 0 0 15px rgba(0, 0, 0, .4);
-webkit-box-shadow: inset 0 0 15px rgba(0, 0, 0, .4);
box-shadow: inset 0 0 15px rgba(0, 0, 0, .4);
}
<div id="container">
<div id="parallelogram">
</div>
</div>
我不知道如何在左下角附近创建(或模拟)倒圆角。
或者可能有概念上不同(更好)的解决方案可用?
更新: 我想出了如何完全用 CSS 创建 shape I need。
#container {
padding-top: 100px;
background: red;
width: 100%;
height: 100%;
overflow: hidden;
}
#parallelogram {
margin-left: 400px;
width: 100%;
height: 900px;
-webkit-transform: skew(-15deg);
-moz-transform: skew(-15deg);
-o-transform: skew(-15deg);
transform: skew(-15deg);
background: white;
-moz-border-top-left-radius: 100px;
-webkit-top-left-border-radius: 100px;
border-top-left-radius: 100px;
}
#bottom {
height: 200px;
width: 100%;
background: white;
}
#bottom-corner {
height: 100px;
width: 300px;
margin-left: -34px;
background: red;
-moz-border-bottom-right-radius: 100px;
-webkit-bottom-right-border-radius: 100px;
border-bottom-right-radius: 100px;
-webkit-transform: skew(-15deg);
-moz-transform: skew(-15deg);
-o-transform: skew(-15deg);
transform: skew(-15deg);
}
<div id="container">
<div id="parallelogram">
</div>
<div id="bottom">
<div id="bottom-corner">
</div>
</div>
</div>
然而,这仍然不是最终的解决方案,因为形状不允许我使用我想要的那种背景效果。这是我尝试时发生的情况:fiddle.
#container {
padding-top: 100px;
background: white url(http://famok.com/wp-content/uploads/2016/10/WhiteOnWhite.jpg) bottom left / 26px 32px repeat;
width: 100%;
height: 100%;
overflow: hidden;
}
#parallelogram {
margin-left: 400px;
width: 100%;
height: 900px;
-webkit-transform: skew(-15deg);
-moz-transform: skew(-15deg);
-o-transform: skew(-15deg);
transform: skew(-15deg);
background: white;
-moz-border-top-left-radius: 100px;
-webkit-top-left-border-radius: 100px;
border-top-left-radius: 100px;
-moz-box-shadow: inset 0 0 15px rgba(0, 0, 0, .4);
-webkit-box-shadow: inset 0 0 15px rgba(0, 0, 0, .4);
box-shadow: inset 0 0 15px rgba(0, 0, 0, .4);
}
#bottom {
height: 200px;
width: 100%;
background: white;
-moz-box-shadow: inset 0 0 15px rgba(0, 0, 0, .4);
-webkit-box-shadow: inset 0 0 15px rgba(0, 0, 0, .4);
box-shadow: inset 0 0 15px rgba(0, 0, 0, .4);
}
#bottom-corner {
height: 100px;
width: 300px;
margin-left: -34px;
background: white url(http://famok.com/wp-content/uploads/2016/10/WhiteOnWhite.jpg) top left / 26px 32px repeat;
-moz-border-bottom-right-radius: 100px;
-webkit-bottom-right-border-radius: 100px;
border-bottom-right-radius: 100px;
-webkit-transform: skew(-15deg);
-moz-transform: skew(-15deg);
-o-transform: skew(-15deg);
transform: skew(-15deg);
-moz-box-shadow: 0 0 15px rgba(0, 0, 0, .4);
-webkit-box-shadow: 0 0 15px rgba(0, 0, 0, .4);
box-shadow: 0 0 15px rgba(0, 0, 0, .4);
}
<div id="container">
<div id="parallelogram">
</div>
<div id="bottom">
<div id="bottom-corner">
</div>
</div>
</div>
稍后更新: 经过反复试验,我最终得到了一个 ridiculously crude hack solution,达到了我需要的视觉效果:
#container {
padding-top: 100px;
background: white url(http://famok.com/wp-content/uploads/2016/10/WhiteOnWhite.jpg) top left / 26px 32px repeat;
width: 100%;
height: 100%;
overflow: hidden;
}
#parallelogram {
margin-left: 385px;
width: 100%;
height: 900px;
-webkit-transform: skew(-15deg);
-moz-transform: skew(-15deg);
-o-transform: skew(-15deg);
transform: skew(-15deg);
background: white;
-moz-border-top-left-radius: 100px;
-webkit-top-left-border-radius: 100px;
border-top-left-radius: 100px;
-moz-box-shadow: inset 0 15px rgba(0, 0, 0, .4);
-webkit-box-shadow: inset 0 0 15px rgba(0, 0, 0, .4);
box-shadow: inset 0 0 15px rgba(0, 0, 0, .4);
}
#bottom-rounded-corner {
height: 122px;
position: relative;
width: 200%;
z-index: 1000;
margin-top: -80px;
margin-left: -185px;
background: url(http://famok.com/wp-content/uploads/2016/11/CornerAndMask.png) top left no-repeat;
}
#bottom-white {
height: 100px;
width: 100%;
background: white;
}
<div id="container">
<div id="parallelogram">
</div>
<div id="bottom-rounded-corner">
</div>
<div id="bottom-white">
</div>
</div>
尽我所能尝试实现下面 Harry 建议的概念上更好的替代方案,但我无法使用它来创建我想要的效果。如果有人可以提供帮助,无论是通过展示如何去做,还是通过对我的解决方案提出优化建议,我仍然会很感激。
提前致谢!
对复杂形状使用 SVG 而不是 CSS:
正如我在评论中提到的,请不要使用 CSS 来创建如此复杂的形状。 SVG 是此类复杂内容的推荐工具。 SVG 易于创建和维护,默认情况下它们也是响应式的(可扩展的),因此它有很多优点。
创建 S 形:
使用 SVG 本身创建 S 形曲线非常简单,只需要一个路径元素:
M0,750
将虚构的笔移动到靠近 SVG 元素的左下角(坐标设置为略低于 SVG 的高度,以便在底部有一个间隙,阴影将可见)。
L250,750
从点 (0,768) 到 (250,768) 生成水平 L 直线
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
和 circle
元素创建了一个圆点图案,但在 SVG 本身中创建它不是强制性的,我们也可以使用 image
元素并用图像图案填充形状。
如果您想将背景图片(图案)更改为您选择的另一张图片,只需在 image
标签的 xlink:href
属性中指定您图片的 URL就像下面的代码片段一样。根据您的需要和图像,您可能需要更改 pattern
和 image
的 height
和 width
。
<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>
注意:以上演示中使用的图片不是我自己的。转自网络
阴影:
阴影效果是使用 SVG filter
元素以及 feGaussianBlur
、feOffset
和 feMerge
元素创建的。 feGaussianBlur
element blurs the source graphic (our sigmoid) by the specified standard deviation value and the feOffset
offsets the resulting image by the dx
, dy
values. The original image and the blurred one are the merged using feMerge
. The feFlood
and the feComposite
are added just in case you want to give the shadow a different color. The colors can be specified using the flood-color
and flood-opacity
attributes. (The method for changing the SVG drop-shadow's color was taken from this answer 作者:Joe W.)
添加文本:
现在这是整个事情中真正棘手的部分。如果您只需要将文本放置在页面的纯色区域,那么您需要谨慎使用定位属性。如果文本很小或只有一行文本,那么我们可以像我之前链接的演示中那样使用 SVG text
元素本身。如果不是,那么您必须确保文本的容器框不会重叠到 S 形区域。
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>
我们可以尝试使用 CSS shape-outside
属性 但是 browser support for that is pretty poor at the moment. Here is a demo using this shape-outside
property. Could not host it in-site because it needed creating a separate SVG file. The demo is an adapted version of the one provided in the W3C CSS Shapes Spec.
替代方法:(将图案应用于容器而不是 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>
这里是 Plunker Demo 的替代方法。这比前一个稍微复杂一些,因为这里我们需要一个 SVG 来生成纯色区域(用作 img
),另一个 SVG 是用于 [=46] 的反转(图案区域) =].
我想为全屏布局创建一个类似 sigmoid curve 的形状,在一侧显示装饰图案背景,在另一侧显示纯色背景,以便文本显示放在它上面。
目标是拥有一个全屏页面,其左上角填充有图案,页面的其余部分只有白色背景。
JSFiddle:Unfinished sigmoid curve
#container {
padding-top: 10%;
padding-bottom: 10%;
background: white url(http://famok.com/wp-content/uploads/2016/10/WhiteOnWhite.jpg) top left / 26px 32px repeat;
width: 100%;
height: 100%;
overflow: hidden;
}
#parallelogram {
margin-left: 35%;
width: 100%;
height: 900px;
-webkit-transform: skew(-15deg);
-moz-transform: skew(-15deg);
-o-transform: skew(-15deg);
transform: skew(-15deg);
background: white;
-moz-border-radius: 100px;
-webkit-border-radius: 100px;
border-radius: 100px;
-moz-box-shadow: inset 0 0 15px rgba(0, 0, 0, .4);
-webkit-box-shadow: inset 0 0 15px rgba(0, 0, 0, .4);
box-shadow: inset 0 0 15px rgba(0, 0, 0, .4);
}
<div id="container">
<div id="parallelogram">
</div>
</div>
我不知道如何在左下角附近创建(或模拟)倒圆角。
或者可能有概念上不同(更好)的解决方案可用?
更新: 我想出了如何完全用 CSS 创建 shape I need。
#container {
padding-top: 100px;
background: red;
width: 100%;
height: 100%;
overflow: hidden;
}
#parallelogram {
margin-left: 400px;
width: 100%;
height: 900px;
-webkit-transform: skew(-15deg);
-moz-transform: skew(-15deg);
-o-transform: skew(-15deg);
transform: skew(-15deg);
background: white;
-moz-border-top-left-radius: 100px;
-webkit-top-left-border-radius: 100px;
border-top-left-radius: 100px;
}
#bottom {
height: 200px;
width: 100%;
background: white;
}
#bottom-corner {
height: 100px;
width: 300px;
margin-left: -34px;
background: red;
-moz-border-bottom-right-radius: 100px;
-webkit-bottom-right-border-radius: 100px;
border-bottom-right-radius: 100px;
-webkit-transform: skew(-15deg);
-moz-transform: skew(-15deg);
-o-transform: skew(-15deg);
transform: skew(-15deg);
}
<div id="container">
<div id="parallelogram">
</div>
<div id="bottom">
<div id="bottom-corner">
</div>
</div>
</div>
然而,这仍然不是最终的解决方案,因为形状不允许我使用我想要的那种背景效果。这是我尝试时发生的情况:fiddle.
#container {
padding-top: 100px;
background: white url(http://famok.com/wp-content/uploads/2016/10/WhiteOnWhite.jpg) bottom left / 26px 32px repeat;
width: 100%;
height: 100%;
overflow: hidden;
}
#parallelogram {
margin-left: 400px;
width: 100%;
height: 900px;
-webkit-transform: skew(-15deg);
-moz-transform: skew(-15deg);
-o-transform: skew(-15deg);
transform: skew(-15deg);
background: white;
-moz-border-top-left-radius: 100px;
-webkit-top-left-border-radius: 100px;
border-top-left-radius: 100px;
-moz-box-shadow: inset 0 0 15px rgba(0, 0, 0, .4);
-webkit-box-shadow: inset 0 0 15px rgba(0, 0, 0, .4);
box-shadow: inset 0 0 15px rgba(0, 0, 0, .4);
}
#bottom {
height: 200px;
width: 100%;
background: white;
-moz-box-shadow: inset 0 0 15px rgba(0, 0, 0, .4);
-webkit-box-shadow: inset 0 0 15px rgba(0, 0, 0, .4);
box-shadow: inset 0 0 15px rgba(0, 0, 0, .4);
}
#bottom-corner {
height: 100px;
width: 300px;
margin-left: -34px;
background: white url(http://famok.com/wp-content/uploads/2016/10/WhiteOnWhite.jpg) top left / 26px 32px repeat;
-moz-border-bottom-right-radius: 100px;
-webkit-bottom-right-border-radius: 100px;
border-bottom-right-radius: 100px;
-webkit-transform: skew(-15deg);
-moz-transform: skew(-15deg);
-o-transform: skew(-15deg);
transform: skew(-15deg);
-moz-box-shadow: 0 0 15px rgba(0, 0, 0, .4);
-webkit-box-shadow: 0 0 15px rgba(0, 0, 0, .4);
box-shadow: 0 0 15px rgba(0, 0, 0, .4);
}
<div id="container">
<div id="parallelogram">
</div>
<div id="bottom">
<div id="bottom-corner">
</div>
</div>
</div>
稍后更新: 经过反复试验,我最终得到了一个 ridiculously crude hack solution,达到了我需要的视觉效果:
#container {
padding-top: 100px;
background: white url(http://famok.com/wp-content/uploads/2016/10/WhiteOnWhite.jpg) top left / 26px 32px repeat;
width: 100%;
height: 100%;
overflow: hidden;
}
#parallelogram {
margin-left: 385px;
width: 100%;
height: 900px;
-webkit-transform: skew(-15deg);
-moz-transform: skew(-15deg);
-o-transform: skew(-15deg);
transform: skew(-15deg);
background: white;
-moz-border-top-left-radius: 100px;
-webkit-top-left-border-radius: 100px;
border-top-left-radius: 100px;
-moz-box-shadow: inset 0 15px rgba(0, 0, 0, .4);
-webkit-box-shadow: inset 0 0 15px rgba(0, 0, 0, .4);
box-shadow: inset 0 0 15px rgba(0, 0, 0, .4);
}
#bottom-rounded-corner {
height: 122px;
position: relative;
width: 200%;
z-index: 1000;
margin-top: -80px;
margin-left: -185px;
background: url(http://famok.com/wp-content/uploads/2016/11/CornerAndMask.png) top left no-repeat;
}
#bottom-white {
height: 100px;
width: 100%;
background: white;
}
<div id="container">
<div id="parallelogram">
</div>
<div id="bottom-rounded-corner">
</div>
<div id="bottom-white">
</div>
</div>
尽我所能尝试实现下面 Harry 建议的概念上更好的替代方案,但我无法使用它来创建我想要的效果。如果有人可以提供帮助,无论是通过展示如何去做,还是通过对我的解决方案提出优化建议,我仍然会很感激。
提前致谢!
对复杂形状使用 SVG 而不是 CSS:
正如我在评论中提到的,请不要使用 CSS 来创建如此复杂的形状。 SVG 是此类复杂内容的推荐工具。 SVG 易于创建和维护,默认情况下它们也是响应式的(可扩展的),因此它有很多优点。
创建 S 形:
使用 SVG 本身创建 S 形曲线非常简单,只需要一个路径元素:
M0,750
将虚构的笔移动到靠近 SVG 元素的左下角(坐标设置为略低于 SVG 的高度,以便在底部有一个间隙,阴影将可见)。L250,750
从点 (0,768) 到 (250,768) 生成水平 L 直线
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
和 circle
元素创建了一个圆点图案,但在 SVG 本身中创建它不是强制性的,我们也可以使用 image
元素并用图像图案填充形状。
如果您想将背景图片(图案)更改为您选择的另一张图片,只需在 image
标签的 xlink:href
属性中指定您图片的 URL就像下面的代码片段一样。根据您的需要和图像,您可能需要更改 pattern
和 image
的 height
和 width
。
<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>
注意:以上演示中使用的图片不是我自己的。转自网络
阴影:
阴影效果是使用 SVG filter
元素以及 feGaussianBlur
、feOffset
和 feMerge
元素创建的。 feGaussianBlur
element blurs the source graphic (our sigmoid) by the specified standard deviation value and the feOffset
offsets the resulting image by the dx
, dy
values. The original image and the blurred one are the merged using feMerge
. The feFlood
and the feComposite
are added just in case you want to give the shadow a different color. The colors can be specified using the flood-color
and flood-opacity
attributes. (The method for changing the SVG drop-shadow's color was taken from this answer 作者:Joe W.)
添加文本:
现在这是整个事情中真正棘手的部分。如果您只需要将文本放置在页面的纯色区域,那么您需要谨慎使用定位属性。如果文本很小或只有一行文本,那么我们可以像我之前链接的演示中那样使用 SVG text
元素本身。如果不是,那么您必须确保文本的容器框不会重叠到 S 形区域。
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>
我们可以尝试使用 CSS shape-outside
属性 但是 browser support for that is pretty poor at the moment. Here is a demo using this shape-outside
property. Could not host it in-site because it needed creating a separate SVG file. The demo is an adapted version of the one provided in the W3C CSS Shapes Spec.
替代方法:(将图案应用于容器而不是 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>
这里是 Plunker Demo 的替代方法。这比前一个稍微复杂一些,因为这里我们需要一个 SVG 来生成纯色区域(用作 img
),另一个 SVG 是用于 [=46] 的反转(图案区域) =].