我想为全屏布局创建一个sigmoid curve形状,可以在一侧显示装饰性图案背景,在另一侧显示纯色背景,以便放置文字顶部。
我们的目标是拥有一个全屏页面,其中左侧的S形图案充满了图案,而页面的其余部分则只有白色背景。
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在下面提出的概念上更好的替代方案,我无法用它来创造我想要的效果。如果有人可以通过展示如何做到这一点,或者通过提出对我的解决方案的优化,我仍然会感激不尽。
提前谢谢!
答案 0 :(得分:11)
将SVG用于复杂形状而非CSS:
正如我在评论中提到的,请不要使用CSS来创建这样复杂的形状。 SVG是这种复杂内容的推荐工具。 SVG易于创建,维护,默认情况下也具有响应性(可扩展),因此具有很多优点。
创建sigmoid形状:
使用SVG创建sigmoid曲线形状非常简单,只需要一个路径元素:
M0,750
将假想笔移动到靠近SVG元素的左下角(坐标设置略低于SVG的高度,以便在阴影底部有一个间隙将是可见的。L250,750
从点(0,768)到(250,768)生成水平 L ine 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;
}
&#13;
<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>
&#13;
将图案应用于形状:
在上面的演示中,我使用polygon
和circle
元素创建了一个圆点花样,但在SVG中不必创建它,我们也可以使用image
元素并用图像模式填充形状。
如果您想将背景图片(图案)更改为您选择的其他图片,只需在xlink:href
标记的image
属性中指定图片的网址,如下面的代码段所示。根据您的需求和图片,您可能需要更改height
和width
的{{1}}和pattern
。
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>
&#13;
body {
margin: 0;
}
svg {
width: 100%;
height: 100vh;
}
&#13;
注意:上面演示中使用的图像不是我自己的。它来自互联网。
暗影:
使用SVG <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>
元素以及filter
,feGaussianBlur
和feOffset
元素创建阴影效果。 feGaussianBlur
元素按指定的标准偏差值模糊源图形(我们的sigmoid),feOffset
按feMerge
,dx
值偏移结果图像。原始图像和模糊图像是使用feMerge
合并的。添加feFlood
和feComposite
以防您想要为阴影提供不同的颜色。可以使用dy
和flood-color
属性指定颜色。 (改变SVG阴影颜色的方法取自Joe W的this answer。)
添加文字
现在这是整个过程中非常棘手的一点。如果您只需要将文本放在页面的纯色区域,那么您需要仔细使用定位属性。如果文本很小或只是一行文本,那么我们可以使用SVG flood-opacity
元素本身,就像我之前链接的演示一样。如果不是,那么您必须确保文本的容器盒不会重叠到S形区域。
text
&#13;
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;
}
&#13;
我们现在可以尝试使用CSS <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>
属性,但browser support for that is pretty poor。这是使用此shape-outside
属性的demo。无法在现场托管,因为它需要创建单独的SVG文件。该演示版是W3C CSS Shapes Spec中提供的版本的改编版本。
替代方法:(将模式应用于容器而不是SVG)
由于您不希望图像被压扁或拉伸,因此另一种方法是执行以下操作:
shape-outside
,然后将SVG绝对放在元素的顶部。 SVG形状(具有白色填充)将防止图案在另一侧可见。
div.container
&#13;
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;
}
&#13;
以下是替代方法的Plunker Demo。这比前一个要复杂一点,因为在这里我们需要一个SVG来生成纯色区域(用作<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>
)和另一个SVG,它是与{{1一起使用的逆向(图案区域) }}