Dim*_*zov 12 css svg rounded-corners css3 css-shapes
我想为全屏布局创建一个S形曲线形状,在一侧显示装饰性图案背景,在另一侧显示纯色背景,以便将文本放置在其上.
我们的目标是拥有一个带有S形状的左上侧的全屏页面,其中包含图案,页面的其余部分只有白色背景.
JSFiddle:未完成的S形曲线
#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);
}Run Code Online (Sandbox Code Playgroud)
<div id="container">
<div id="parallelogram">
</div>
</div>Run Code Online (Sandbox Code Playgroud)
我无法弄清楚如何在左下角附近创建(或模拟)倒圆角.
或者可能有一个概念上不同(更好)的解决方案?
#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);
}Run Code Online (Sandbox Code Playgroud)
<div id="container">
<div id="parallelogram">
</div>
<div id="bottom">
<div id="bottom-corner">
</div>
</div>
</div>Run Code Online (Sandbox Code Playgroud)
然而,这仍然不是最终解决方案,因为形状不允许我使用我想到的那种背景效果.这是我尝试时会发生的事情:小提琴.
#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);
}Run Code Online (Sandbox Code Playgroud)
<div id="container">
<div id="parallelogram">
</div>
<div id="bottom">
<div id="bottom-corner">
</div>
</div>
</div>Run Code Online (Sandbox Code Playgroud)
稍后更新:经过一些试验和错误后,我最终得到了一个荒谬的粗暴黑客解决方案,实现了我所需的视觉效果:
#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;
}Run Code Online (Sandbox Code Playgroud)
<div id="container">
<div id="parallelogram">
</div>
<div id="bottom-rounded-corner">
</div>
<div id="bottom-white">
</div>
</div>Run Code Online (Sandbox Code Playgroud)
尽量努力实现哈利在下面提出的概念上更好的替代方案,我无法用它来创造我想要的效果.如果有人可以通过展示如何做到这一点,或者通过提出对我的解决方案的优化,我仍然会感激不尽.
先感谢您!
Har*_*rry 11
将SVG用于复杂形状而不是CSS:
正如我在评论中提到的那样,请不要使用CSS来创建这样复杂的形状.SVG是这种复杂内容的推荐工具.SVG易于创建和维护,并且默认情况下它们也具有响应性(可扩展),因此它具有很多优点.
创建S形形状:
使用SVG创建sigmoid曲线形状非常简单,只需要一个路径元素:
M0,750 将假想笔移动到靠近SVG元素的左下角(坐标设置略低于SVG的高度,以便在底部有一个可以看到阴影的间隙).L250,750产生从点(0,768)到(250,768)的水平L ineC650,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;
}Run Code Online (Sandbox Code Playgroud)
<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>Run Code Online (Sandbox Code Playgroud)
将图案应用于形状:
在上面的演示中,我使用了polygon和circle元素创建了一个圆点图案,但是在SVG本身内部创建它并不是必须的,我们也可以使用image元素并用图像模式填充形状.
如果要将背景图像(图案)更改为您选择的其他图像,只需xlink:href在image标记的属性中指定图像的URL,如下面的代码段所示.根据您的需要和形象,你可能不得不改变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>
Run Code Online (Sandbox Code Playgroud)
body {
margin: 0;
}
svg {
width: 100%;
height: 100vh;
}Run Code Online (Sandbox Code Playgroud)
<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>Run Code Online (Sandbox Code Playgroud)
注意:上面演示中使用的图像不是我自己的.它取自互联网.
影子:
阴影效果是通过使用SVG创建的filter元件具有沿feGaussianBlur,feOffset和feMerge元件.所述feGaussianBlur元件由指定的标准偏差值和所述模糊了源图形(我们的乙状结肠)feOffset通过偏移所产生的图像dx,dy的值.原始图像和模糊的图像是合并使用feMerge.在feFlood和feComposite添加,以防万一你想给的阴影不同的颜色.可以使用flood-color和flood-opacity属性指定颜色.(改变SVG阴影颜色的方法取自Joe W.的答案)
添加文字:
现在这是整个事情中非常棘手的一点.如果您只需要将文本放在页面的纯色区域,那么您需要仔细使用定位属性.如果文本很小或只是一行文本,那么我们可以使用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;
}Run Code Online (Sandbox Code Playgroud)
<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>Run Code Online (Sandbox Code Playgroud)
我们可以尝试使用CSS shape-outside属性,但目前浏览器对此的支持非常差.这是使用此属性的演示shape-outside.无法在现场托管,因为它需要创建单独的SVG文件.该演示是W3C CSS Shapes Spec中提供的版本的改编版本.
替代方法:(将模式应用于容器而不是SVG)
由于您不希望图像被压扁或拉伸,因此另一种方法是执行以下操作:
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;
}Run Code Online (Sandbox Code Playgroud)
<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>Run Code Online (Sandbox Code Playgroud)
这是替代方法的Plunker演示.这比前一个复杂一点,因为在这里我们需要一个SVG来产生纯色区域(用作img)和另一个SVG,它是与之相关的逆(图案区域)shape-outside.