前端开发 大前端 W3Cbest

一个专注 WEB 开发的技术博客

0%

CSS形状入门--自定义路径周围的内容包装(CSS Shapes)

CSS Shapes 简介

CSS Shapes 允许我们通过定义文本内容可以环绕的几何形状、图像和渐变,来创建有趣且独特的布局。本次教程会教你如何使用它们。 在 CSS Shapes 问世之前,为网页设计文本自由环绕的杂志式布局几乎是不可能的。相反,网页设计布局传统上一直用网格、盒子和直线构造。 CSS Shapes 允许我们定义文本环绕的几何形状。这些形状可以是圆、椭圆、简单或复杂的多边形,甚至图像和渐变。Shapes 的一些实际设计应用可能是圆形头像周围显示圆形环绕文本,全屏背景图片的简单部位上面展示文本,以及在文章中显示首字下沉。 现在 CSS Shapes 已经获得了现代浏览器的广泛支持,值得一看的是它们提供的灵活性和功能,以确定它们在你的下一个设计项目中是否能派上用场。

注意:截至攥写本文时,CSS Shapes 支持 Firefox、Chrome、Safari 和 Opera,以及 iOS Safari 和 Chrome for Android 等移动浏览器。Shapes 不支持 IE,对 Microsoft Edge 的支持正在考虑中

CSS Shapes 初探

CSS Shapes 的当前实现是 CSS Shapes Module Level 1,它主要包含 [shape-outside]属性。shape-outside 定义了文本环绕的形状。 考虑到有 shape-outside 属性,你可能会想到还有一个相应的 shape-inside 属性,它包含形状内的文本。shape-inside 属性可能会在将来实现,目前它只是 CSS Shapes Module Level 2里面的一个草案,并没有被任何浏览器实现。 在本文中,我们将演示如何使用<basic-shape>数据类型并使用形状函数值设置它,以及使用半透明URL或渐变设置形状。  

基本形状函数

我们可以通过对shape-outside属性应用以下函数值来定义CSS中的各种基本形状:

  • circle()
  • ellipse()
  • inset()
  • polygon()

为了将shape-outside属性应用到元素上,元素必须是浮动的,并且具有定义的高度和宽度。让我们逐一介绍这四个基本形状,并演示如何使用它们。

circle

我们将从 circle() 函数开始。设想如下场景,有一个圆形的作者头像,我们想让头像左浮动并且作者的描述文本环绕它。仅对头像元素使用 border-radius: 50% 不足以使文本呈圆形;文本仍将把头像当成矩形元素。 通过圆形,我们可以演示文本如何按圆形环绕。 首先我们在一个普通的 div 上创建 circle 样式,并且写几段文字(我使用 Bob Ross 语录作为 Lorem Ipsum 文本)。

Example text...

在circle 样式中,我们将元素浮动到左边,给它一个相等的高度和宽度,并将shape-outside设置为circle()。

.circle {
float: left;
height: 200px;
width: 200px;
shape-outside: circle();
}

如果我们访问页面,会看到如下场景。 正如你所看到的,文字围绕着圆形流动,但我们实际上看不到任何形状。将鼠标悬停在Developer Tools中的元素上,将向我们显示正在设置的实际形状。 此时,你可能会认为可以给元素 background 设置颜色或者图片就能看到形状了。我们来试一下。

.circle {
float: left;
height: 200px;
width: 200px;
shape-outside: circle();
background: linear-gradient(to top right, #FDB171, #FD987D);
}

不幸的是,给 circle 设置 background 后会显示一个矩形,这是我们一直试图避免的事情。 我们可以清晰地看到文本在它周围环绕,但是元素本身并没有形状。如果我们想要真实地显示形状函数,就必须使用 clip-path 属性。clip-path 采用许多和 shape-outside 相同的值,所以我们可以给它相同的circle()值。

.circle {
float: left;
height: 200px;
width: 200px;
shape-outside: circle();
clip-path: circle();
background: linear-gradient(to top right, #FDB171, #FD987D);
}

 

在本文剩下的部分,我将使用 clip-path 帮助我们辨认形状。

circle() 函数接收可选的 radius 参数。在我们的例子中,默认 radius 是 50% 或者 100px。使用 circle(50%) 或者 circle(100px) 都将产生和我们已经完成样例的同样结果。 你可能会注意到文本刚好和形状贴合。我们可以使用 shape-margin 属性给形状添加 margin,它可以设置为px、em、% 和任何其他标准的 CSS 测量单位。

.circle {
float: left;
height: 200px;
width: 200px;
shape-outside: circle(25%);
shape-margin: 1rem;
clip-path: circle(25%);
background: linear-gradient(to top right, #FDB171, #FD987D);
}

下面是一个circle radius 设置 25% 并且使用 shape-margin 的例子。 除了 radius,形状函数可以使用 at 定位。默认位置是圆的中心,因此 circle() 也可以被显式设置为 circle(50% at 50% 50%) 或 circle(100px at 100px 100px),这两个值分别是水平和垂直位置。 为了搞清楚 position 的作用,我们可以设置水平位置值为 0 来创造一个完美的半圆。

circle(50% at 0 50%);

这种坐标定位系统称为参考框。

稍后我们将学习如何使用图像代替形状或者渐变。现在我们将继续进行下一个形状函数。

Ellipse

ellipse() 和 circle() 函数类似,只是它会创造椭圆。为了演示,我们创建一个 ellipse 元素和样式。

Example text...

.ellipse {
float: left;
shape-outside: ellipse();
clip-path: ellipse();
width: 150px;
height: 300px;
background: linear-gradient(to top right, #F17BB7, #AD84E3);
}

这次,我们设置不同的 height 和 width 创建一个垂直拉长的椭圆。 ellipse() 和 circle()的区别在于,ellipse有两个半径rx和ry,即x轴半径和y轴半径。因此,上述例子也可以写成:

ellipse(75px 150px);

circles 和 ellipses 的位置参数是一样的。除了是测量单位,半径也包括 farthest-side 和 closest-side 的选项。 closest-side 是指从参考框的中心到最近边的长度,相反,farthest-side 是指从参考框的中心到最远边的长度。这意味着如果未设置默认值以外的位置,这两个值将无效。 下面演示了在 ellipse() 上翻转 closest-side 和 farthest-side 的区别,在X轴和Y轴上偏移25%。

ellipse(farthest-side closest-side at 25% 25%)

ellipse(farthest-side closest-side at 25% 25%)

 

Inset

到目前为止我们只处理了圆形的形状,但是我们可以使用 inset() 函数定义内嵌矩形。

Example text...

.inset {
float: left;
shape-outside: inset(75px);
clip-path: inset(75px);
width: 300px;
height: 300px;
background: linear-gradient(#58C2ED, #1B85DC);
}

在本例中,我们将创建一个300px×300px的矩形,并在所有边内嵌75px。这样我们就得到了150px×150px的图像周围有75px的空间。 我们可以看到矩形是内嵌的,文本忽略了内嵌区域。 inset() 形状也可以使用 round 参数接收 border-radius,并且文本会识别圆角,就像本例中所有边都是 25px 内嵌和 75px 圆角。

inset(25px round 75px)

像 padding 或 margin 简写,inset 值以顺时针方式(inset(25px 25px 25px 25px))接收 top right bottom left,并且只传一个值将使四条边都相同(inset(25px))。  

Polygon

形状函数中最有趣和最灵活的是 polygon(),它可以采用一系列 x 和 y 点来制作任何复杂形状。数组里的每个元素代表 _x_i _y_i,将被写成 polygon(x1 y1, x2 y2, x3 y3…) 等等。 我们可以为多边形设置的点集数量最少为 3,这将创建一个三角形。

Example text...

.polygon {
float: left;
shape-outside: polygon(0 0, 0 300px, 200px 300px);
clip-path: polygon(0 0, 0 300px, 200px 300px);
height: 300px;
width: 300px;
background: linear-gradient(to top right, #86F7CC, #67D7F5);
}

  在这个形状中,第一个点是 0 0,div 中最左上角的点。第二个点是 0 300px,它是 div 中最左下角的点。第三个也就是最后一个点是 200px 300px,它在 X 轴的 2/3 处并且也在底部。最终的形状是这样: polygon() 形状函数的一个有趣用法是文本内容可以在两个或以上形状中环绕。因为 polygon() 形状是如此灵活和动态,这给我们制作真正独特的杂志式布局提供了一个最好机会。在本例中,我们将把文本放在两个多边形中。

Example text...

.left {
float: left;
shape-outside: polygon(0 0, 0 300px, 200px 300px);
clip-path: polygon(0 0, 0 300px, 200px 300px);
background: linear-gradient(to top right, #67D7F5, #86F7CC);
height: 300px;
width: 300px;
}
.right {
float: right;
shape-outside: polygon(200px 300px, 300px 300px, 300px 0, 0 0);
clip-path: polygon(200px 300px, 300px 300px, 300px 0, 0 0);
background: linear-gradient(to bottom left, #67D7F5, #86F7CC);
height: 300px;
width: 300px;
}

显然,想要手动创造你自己的复杂形状是非常困难的。幸运的是,你可以用一些工具来创建多边形。Firefox 有一个内置的形状编辑器,你可以在 Inspector 中通过点击多边形使用。 目前,Chrome有一些可以使用的扩展,比如CSS shape Editor。 多边形可以用来剪切图像或其他元素周围的形状。在另一个例子中,我们可以通过在大字母周围绘制多边形来创建首字下沉。

R

Example text...

.letter {
float: left;
font-size: 400px;
font-family: Georgia;
line-height: .8;
margin-top: 20px;
margin-right: 20px;
shape-outside: polygon(5px 14px, 233px 20px, 246px 133px, 189px 167px, 308px 304px, 0px 306px) content-box;
clip-path: polygon(5px 14px, 233px 20px, 246px 133px, 189px 167px, 308px 304px, 0px 306px);
}

URLs

CSS Shapes 一个令人激动的特性是你不必每次都通过形状函数明确定义;你也可以使用半透明图像的 url 来定义形状,这样文本就会自动环绕它。 需要注意的是,所使用的图像必须与CORS兼容,否则您将得到如下所示的错误。

Access to image at ‘file:///users/tania/star.png’ from origin ‘null’
has been blocked by CORS policy: The response is invalid.

  在同一个服务器上提供图像将会保证你不会遇到上面的错误。 与其他示例不同,我们将使用 img 代替 div。这次的 CSS 很简单——只需将url()放到shape-outside属性中,就像使用 background-image 一样。

Example text...

.star {
float: left;
height: 350px;
width: 350px;
shape-outside: url(‘./star.png’)
}

因为我使用了透明背景的星星图像,所以文本知道哪些区域是透明的,哪些区域是不透明的,并相应地对自己进行自适应布局。

Gradients

最后,渐变也可以用来当成形状。渐变和图像一样,就像我们上面使用的图像示例一样,文本也将知道在透明部分环绕。 我们将使用渐变的一个新属性 —— shape-image-threshold。shape-image-threshold 定义形状的 alpha 通道阈值,或者图像透明的百分比值。 我们将制作一个渐变例子,它是 50%/50% 的颜色和透明分割,并且设置 shape-image-threshold 为 .5,意味着超过 50% 不透明的所有像素都应被视为图像的一部分。

Example text...

.gradient {
float: left;
height: 300px;
width: 100%;
background: linear-gradient(to bottom right, #86F7CC, transparent);
shape-outside: linear-gradient(to bottom right, #86F7CC, transparent);
shape-image-threshold: .5;
}

  我们可以看到渐变在不透明和透明的中心完美地对角线分割。

总结

在这篇文章中,我们学习了 CSS Shapes 的三个属性 shape-outside、shape-margin 和 shape-image-threshold。我们也了解到如何使用函数值创建可供文本环绕的圆、椭圆、内嵌矩形以及复杂的多边形,并且演示了形状如何检测图像和渐变的透明部分。 你可以在如下 demo 中找到本文中用到的所有例子,也可以下载源文件

See the Pen CSS Shapes Examples by w3cbest.com (@w3cbest) on CodePen.

文章来源: https://tympanus.net/codrops/2018/11/29/an-introduction-to-css-shapes/ 相关阅读参考:https://alistapart.com/article/css-shapes-101 相关阅读参考:https://www.html5rocks.com/en/tutorials/shapes/getting-started/#toc-manual-shapes

坚持技术创作分享,您的支持将鼓励我继续创作!