我想创建一个 sigmoid curve类似形状的全屏布局,一侧显示装饰性图案背景,另一侧显示纯色背景,用于将文本放置在其顶部。
目标是有一个全屏页面,左上 Angular 有一个类似 sigmoid 的图案,页面的其余部分只是有白色背景。
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>
我不知道如何在左下 Angular 附近创建(或模拟)倒圆 Angular 。
或者也许有一个概念上不同(更好)的解决方案可用?
更新:我想出了如何创建 shape I need完全用CSS。
#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 易于创建、维护,并且默认情况下它们也是响应式的(可缩放的),因此它有很多优点。
创建 sigmoid 形状:
使用 SVG 本身创建 sigmoid 曲线形状非常简单,只需要一个路径元素:
M0,750
将假想的笔靠近 SVG 元素的左下 Angular (坐标设置为略低于 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
创建了一个圆点图案。和 circle
元素,但在 SVG 本身中创建它不是强制性的,我们也可以使用 image
元素并用图像图案填充形状。如果您想将背景图片(图案)更改为您选择的另一张图片,只需在
xlink:href
中指定您图片的 URL。 image
的属性像下面的代码片段一样标记。根据您的需求和形象,您可能需要更改 height
和 width
的 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>
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
元素通过指定的标准偏差值和 feOffset
模糊源图形(我们的 sigmoid)将结果图像偏移 dx
, dy
值。原始图像和模糊图像使用 feMerge
合并. feFlood
和 feComposite
以防万一你想给阴影一个不同的颜色。可以使用 flood-color
指定颜色和 flood-opacity
属性。 (更改 SVG 阴影颜色的方法来自 Joe W.的 this answer。)添加文本:
现在这是整个事情中真正棘手的一点。如果您只需要将文本放置在页面的纯色区域,则需要谨慎使用定位属性。如果文本很小或只有一行文本,那么我们可以使用 SVG
text
元素本身就像我之前链接的演示中一样。如果不是,那么您必须确保文本的容器框不会重叠到 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>
我们可以尝试使用 CSS
shape-outside
属性(property)但browser support for that is pretty poor此刻。这是一个 demo使用这个 shape-outside
属性(property)。无法在现场托管它,因为它需要创建一个单独的 SVG 文件。该演示是 W3C CSS Shapes Spec 中提供的版本的改编版本。 .替代方法: (将模式应用于容器而不是 SVG)
由于您不希望图像被压扁或拉伸(stretch),另一种方法是执行以下操作:
div.container
然后将 SVG 绝对放在元素的顶部。 SVG 形状(具有白色填充)将防止图案在另一侧可见。 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 是与 shape-outside
一起使用的相反(图案区域)。 .
关于css - 带 CSS 的 Sigmoid 曲线形状,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40350457/