最近,使用CSS属性shape-outside
来创建有趣和不寻常的文本和布局效果的演示不断涌现。 ( 这是 Mandy Michael 的一个例子 )
shape-outside
属性( CSS Shapes模块的一部分 )允许我们将文本包装在对象的形状周围。 您希望文本环绕的对象必须具有宽度和高度,并向左或向右浮动。 这是我们要做的最简单的代码:
.shape {
width: 200px;
height: 200px;
float: left;
shape-outside: circle(50%);
}
这将在圆形区域周围包裹一段文本,如下所示:
此处,文本将以圆形环绕。 您可以使用polygon()创建更复杂的形状:
.shape {
width: 200px;
height: 350px;
float: left;
shape-outside: polygon(0 0undefined 50% 0%undefined 90% 50%undefined 50% 100%undefined 0 100%);
}
在这里,我使用x和y坐标对“绘制”多边形。 当前,尽管文本将环绕形状,但.shape
对象本身仍将是正方形。 如果我们给它提供背景色,您会明白我的意思:
如果我们希望形状具有背景色并让文本环绕它怎么办? 如果我们希望物体是圆形的,我们当然可以给它一个50%的border-radius
。 但是,当我们使用更复杂的形状时,如果我们希望它遵循与shape-outside
属性相同的路径怎么办? 在这种情况下,我们可以使用clip-path
,并赋予它与shape-outside
属性相同的值。 我们还可以使用shape-margin
属性在形状和环绕它的内容之间增加一些距离:
.shape {
width: 200px;
height: 350px;
background-color: #EC407A;
float: left;
shape-outside: polygon(0 0undefined 50% 0%undefined 90% 50%undefined 50% 100%undefined 0 100%);
clip-path: polygon(0 0undefined 50% 0%undefined 90% 50%undefined 50% 100%undefined 0 100%);
shape-margin: 10px;
}
这是完整的演示:
倒转形状
如果我们想剪切文本的背景,事情会变得有些复杂。 现在,我们需要反转剪切路径–也就是说,我们需要创建一条形状的路径,如果您将原始路径从矩形中剪切出来,则该形状会保留下来。 这需要一点数学运算,但是我们可以创建一些有趣的效果。 不用说,多边形越复杂,创建“倒置”版本的难度就越大! 我发现将其绘制在纸上并记下多边形中每个点的坐标是有帮助的。
这是一个具有反向剪切路径的演示:
注意,可以在clip-path
多边形中混合使用像素单位和百分比。 我在水平尺寸上使用像素,因为它必须是固定宽度才能正确地与形状路径相对应,但是垂直单位的百分比是万一,以防以后要调整高度–这样我就不需要了重新计算所有垂直坐标。
这给人的印象是文本在形状内,但有一些限制:
- 我们目前仅在一侧修剪,因此我们的形状还不是很有趣。
- 如果要在形状上添加
box-shadow
,则在裁剪时将不可见–除非box-shadow
具有inset
值。 但是,阴影将位于外部元素上,而不是剪切掉的部分。
我将一一解决这两个问题。
内部形状
几年前, Sara Soueidan撰写了有关CSS Shapes的精彩介绍,其中还展示了如何使用shape-inside
属性将文本包装在shape-inside
,该属性当时对浏览器的支持非常有限。 现在已经取消了shape-inside
支持(尽管它是Level 2规范的一部分),这意味着您目前无法在任何地方使用它。 造成这种情况的部分原因是对CSS区域的支持被取消,该区域将处理所有溢出的文本内容。 但是,通过巧妙地使用shape-outside
,我们可以创建类似的效果。 如果我有两个分别向左和向右浮动的多边形,则文本将填充它们中间的空间:
.shape {
float: left;
width: 200px;
height: 460px;
shape-outside: polygon(0 0undefined 100px 0undefined 180px 50%undefined 100px 100%undefined 0 100%);
shape-margin: 10px;
}
.shape2 {
float: right;
width: 200px;
height: 460px;
shape-outside: polygon(0 0undefined 100% 0undefined 100% 100%undefined 0 100%undefined 100px 50%);
shape-margin: 10px;
}
如果要设置文本背景的样式并在这种情况下将其剪裁掉,则需要以某种方式计算出两者之间的空间的clip-path
值。 我发现最简单的方法是将路径视为同一矩形的一部分。 然后,您可以绘制路径上每个点的坐标。
方便地,您也可以在clip-path()
函数内部使用calc()
,如果您不使用精确的宽度,这很有用。
这是演示:
作为附带说明,Bennet Feeley的工具Clippy对于快速获取剪切路径坐标非常有用。
创建盒子阴影效果
正如我所提到的,将一个盒形阴影添加到被裁剪的元素将没有任何效果。 但是我们可以使用伪元素创建类似的效果。 将clip-path
移动到伪元素( ::before
)意味着我们可以创建另一个具有相同坐标的绝对定位的裁剪伪元素( ::after
),并应用一些效果以使其看起来像元素是浮动在页面上方:
使用SVG
如果背景具有透明背景(SVG或PNG),我们还可以将图像用作shape-outside
值,这可以使我们产生一些更有趣的路径。 要使用图像,请在shape-outside
属性值中引用URL,如下所示:
.shape {
...
shape-outside: url(shape.svg);
}
这是一个简单的演示:
我对将SVG和剪切路径结合使用的可能性感到非常兴奋,但这并不是那么简单。 如果要为剪切路径值使用相同的SVG路径,就会遇到困难。 通过将SVG内联写入标记中,我们可以将SVG用于剪切路径:
<div class="shape">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 157.8 250">
<clipPath id="clip">
<path d="M140 250H0V0h140s40 36 0 125 0 125 0 125z"/>
</clipPath>
<path d="M140 250H0V0h140s40 36 0 125 0 125 0 125z"/>
</svg>
</div>
然后,在clip-path属性值中引用clipPath ID:
.container {
clip-path: url(#clip);
}
但是,这将夹住容器的错误部分! 我在这里要做的是剪切倒置的部分(包裹我们形状的部分)。
我这样做的方法是在Illustrator(或类似的矢量图形程序)中的矩形内绘制形状,以使您实际上具有两个形状-原始形状及其反色。
然后,您可以在SVG代码中包含剪辑形状,该形状将正确放置在SVG viewBox中:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 950 250" width="0" height="0">
<clipPath id="clip">
<path d="M140 0s40 36 0 125 0 125 0 125h810V0H140z"/>
</clipPath>
</svg>
您可能会注意到,我包括width="0"
和height="0"
–这将确保SVG不占用任何空间,因为我们只需要引用clipPath
,我们不希望它可见在页面上。
在本演示中,我引用了一个外部SVG shape-outside
财产,为内联SVG clip-path
属性:
使用SVG模拟形状内部
如果我们要裁剪的容器的两侧 ,对左边和右边的文字环绕事情变得更加复杂。 在下面的演示中,我使用与上一个相同的技术,但是我在元素的左右浮动。 每个形状的宽度不得超过50%,否则它们将包裹在下面。 因此,当我在Illustrator中裁剪SVG时,我将原始形状分为两半并创建了两个SVG形状(用于shape-outside
属性)。
对于每种形状, viewBox
恰好是容器总宽度的一半,但是path
仅占其中一部分。 该演示演示了最终结果,并利用了本文前面详细介绍的其他一些技术。
请注意,由于我使用的是固定尺寸,因此只能在960px以上的屏幕上使用!
如果您想了解有关SVG的更多信息,Sara Soueidan的博客上有很多很棒的文章,她详细介绍了viewBox
属性和SVG坐标系。
浏览器支持和其他想法
浏览器对CSS Shapes的支持约为80%,但Edge除外。 尽管应该在下一个更新中完全实现,但Firefox的实现目前处于标记之下。 因此,牢记渐进增强方法是明智的。
我看不到的一件事是Shape的UX视图。 将文本的左边缘环绕复杂的形状对于可读性不是很好,虽然看到一些有趣的艺术布局令人兴奋,但对于对用户至关重要的内容,请务必谨慎使用Shapes。
我认为,除了浏览器支持之外,这种方法未得到广泛使用的另一个原因是,进行响应式控制可能有些棘手。 在最后一个示例中,我在很大程度上依赖于x和y轴上的固定大小来获得所需的效果。 如果您的文本长度不确定,则将文本包装在形状中的效果可能在不同的断点处效果不佳,因此对于动态内容,通常不是一个好的选择。 就是说,在布局方面绝对有一个试验的地方,很高兴看到网络创意的新时代蓬勃发展。