形状概述

CSS 形状模块用于在 CSS 中描述几何形状。本文概述了如何使用形状来使文本环绕那些不一定是矩形的浮动元素。

当你将一个元素向左浮动时,文本会以矩形的方式环绕在该元素的右侧和下方。而使用 CSS 形状,你可以应用一个圆形,这样文本就会沿着圆形的边缘进行环绕。

有多种方法可以创建这个圆形。在本指南中,我们将了解 CSS 形状的工作原理以及如何使用它们。

该规范定义了什么?

该规范定义了一些属性,包括:

  • shape-outside — 允许定义基本形状。
  • shape-image-threshold — 设置一个不透明度阈值。如果使用图像来定义形状,只有图像中不透明度等于或大于该阈值的部分才会被用于形状。任何其他部分都将被忽略。
  • shape-margin — 为定义的形状设置外边距。

定义基本形状

shape-outside 属性允许我们定义一个形状。它接受在 <basic-shape> 数据类型中指定的各种值来定义不同的形状。

在下面的示例中,一张图片向左浮动。我们应用了 shape-outside 属性,其值为 circle(50%)。结果是,内容现在会沿着圆形弯曲,而不是沿着图片盒子创建的矩形排列。

html
<div class="box">
  <img
    alt="An orange hot air balloon as seen from below"
    src="https://mdn.github.io/shared-assets/images/examples/round-balloon.png" />
  <p>
    One November night in the year 1782, so the story runs, two brothers sat
    over their winter fire in the little French town of Annonay, watching the
    grey smoke-wreaths from the hearth curl up the wide chimney. Their names
    were Stephen and Joseph Montgolfier, they were papermakers by trade, and
    were noted as possessing thoughtful minds and a deep interest in all
    scientific knowledge and new discovery. Before that night—a memorable night,
    as it was to prove—hundreds of millions of people had watched the rising
    smoke-wreaths of their fires without drawing any special inspiration from
    the fact.
  </p>
</div>
css
body {
  font: 1.2em / 1.4 sans-serif;
}

img {
  float: left;
  shape-outside: circle(50%);
}

这里我们使用了所有现代浏览器都支持的 circle() 函数。如果我们使用一个未得到完全支持的较新形状类型,不支持的浏览器的用户会看到内容沿着矩形的边缘流动,因为图片是浮动的。形状是一种视觉上的渐进增强。

基本形状

circle(50%) 是一个基本形状的例子。该规范定义了几个 <basic-shape> 值,包括:

其中三个函数仅定义矩形。使用 inset() 函数,你可以定义四个偏移值,从而将任何环绕内容的行框拉得比原本更靠近对象。rect() 函数通过指定距包含块顶部和左侧边缘的距离来定义一个矩形。xywh() 函数通过指定距参考框顶部和左侧边缘的距离,并从该起点设置矩形的宽度和高度来工作。

我们已经看到了 circle() 如何创建一个圆形。ellipse() 本质上是一个被压扁的圆。如果这些基本形状都不能满足需求,你可以使用 polygon() 函数创建更复杂的形状,该函数允许定义一系列的线段。path()shape() 函数可用于通过一系列线段、曲线和移动命令创建任意形状。

在我们的基本形状指南中,我们探讨了每种可能的基本形状以及如何创建它们。

基于盒子值的形状

形状也可以围绕盒子值创建。因此,你可以在以下盒子上创建形状:

  • border-box
  • padding-box
  • content-box
  • margin-box

在下面的示例中,你可以将值 border-box 更改为任何其他允许的值,以观察形状如何靠近或远离盒子。

html
<div class="box">
  <div class="shape"></div>
  <p>
    One November night in the year 1782, so the story runs, two brothers sat
    over their winter fire in the little French town of Annonay, watching the
    grey smoke-wreaths from the hearth curl up the wide chimney. Their names
    were Stephen and Joseph Montgolfier, they were papermakers by trade, and
    were noted as possessing thoughtful minds and a deep interest in all
    scientific knowledge and new discovery. Before that night—a memorable night,
    as it was to prove—hundreds of millions of people had watched the rising
    smoke-wreaths of their fires without drawing any special inspiration from
    the fact.
  </p>
</div>
css
body {
  font: 1.2em / 1.4 sans-serif;
}

.shape {
  background-color: rebeccapurple;
  height: 150px;
  width: 150px;
  padding: 20px;
  margin: 20px;
  border-radius: 50%;
  float: left;
  shape-outside: border-box;
}

要更详细地探索盒子值,请参阅我们关于基于盒子值的形状的指南。

基于图像的形状

一种有趣的生成路径的方法是使用带有 Alpha 通道的图像——文本会环绕图像中不透明的部分。这允许环绕内容覆盖在图像上,或者使用一个从未在页面上显示的图像,纯粹作为一种创建复杂形状的方法,而无需仔细绘制多边形。

请注意,以这种方式使用的图像必须是 CORS 兼容的,否则 shape-outside 的行为将如同值为 none 一样,你将得不到任何形状。

在下一个示例中,我们有一个带有完全透明区域的图像,并且我们使用该图像的 URL 作为 shape-outside 的值。形状是围绕不透明区域——即气球的图像——创建的。

html
<div class="box">
  <img
    alt="An orange hot air balloon as seen from below"
    src="https://mdn.github.io/shared-assets/images/examples/round-balloon.png" />
  <p>
    One November night in the year 1782, so the story runs, two brothers sat
    over their winter fire in the little French town of Annonay, watching the
    grey smoke-wreaths from the hearth curl up the wide chimney. Their names
    were Stephen and Joseph Montgolfier, they were papermakers by trade, and
    were noted as possessing thoughtful minds and a deep interest in all
    scientific knowledge and new discovery. Before that night—a memorable night,
    as it was to prove—hundreds of millions of people had watched the rising
    smoke-wreaths of their fires without drawing any special inspiration from
    the fact.
  </p>
</div>
css
body {
  font: 1.2em / 1.4 sans-serif;
}

img {
  float: left;
  shape-outside: url("https://mdn.github.io/shared-assets/images/examples/round-balloon.png");
}

shape-image-threshold

shape-image-threshold 属性用于设置图像透明度的阈值,该阈值用于定义形状所使用的图像区域。如果 shape-image-threshold 的值为 0.0(这是初始值),则该区域必须是完全透明的。如果值为 1.0,则该区域是完全不透明的。介于两者之间的值意味着你可以将半透明区域设置为形状的定义区域。

如果我们使用渐变作为定义形状的图像,你就可以看到阈值的作用。在下面的示例中,如果你更改阈值,形状所采用的路径会根据你选择的不透明度级别而改变。

html
<div class="box">
  <div class="shape"></div>
  <p>
    One November night in the year 1782, so the story runs, two brothers sat
    over their winter fire in the little French town of Annonay, watching the
    grey smoke-wreaths from the hearth curl up the wide chimney. Their names
    were Stephen and Joseph Montgolfier, they were papermakers by trade, and
    were noted as possessing thoughtful minds and a deep interest in all
    scientific knowledge and new discovery. Before that night—a memorable night,
    as it was to prove—hundreds of millions of people had watched the rising
    smoke-wreaths of their fires without drawing any special inspiration from
    the fact.
  </p>
</div>
css
body {
  font: 1.2em / 1.4 sans-serif;
}

.shape {
  float: left;
  width: 200px;
  height: 200px;
  background-image: linear-gradient(
    45deg,
    rebeccapurple,
    transparent 80%,
    transparent
  );
  shape-outside: linear-gradient(
    45deg,
    rebeccapurple,
    transparent 80%,
    transparent
  );
  shape-image-threshold: 0.4;
}

要了解有关从图像创建形状的更多信息,请参阅基于图像的形状指南。

shape-margin 属性

shape-margin 属性为 shape-outside 添加一个外边距。这会进一步缩短环绕形状的任何内容的行框,使其远离形状本身。

在下面的示例中,我们为一个基本形状添加了 shape-margin。更改外边距,使文本比形状默认路径更远离。

html
<div class="box">
  <img
    alt="An orange hot air balloon as seen from below"
    src="https://mdn.github.io/shared-assets/images/examples/round-balloon.png" />
  <p>
    One November night in the year 1782, so the story runs, two brothers sat
    over their winter fire in the little French town of Annonay, watching the
    grey smoke-wreaths from the hearth curl up the wide chimney. Their names
    were Stephen and Joseph Montgolfier, they were papermakers by trade, and
    were noted as possessing thoughtful minds and a deep interest in all
    scientific knowledge and new discovery. Before that night—a memorable night,
    as it was to prove—hundreds of millions of people had watched the rising
    smoke-wreaths of their fires without drawing any special inspiration from
    the fact.
  </p>
</div>
css
body {
  font: 1.2em / 1.4 sans-serif;
}
img {
  float: left;
  shape-outside: circle(50%);
  shape-margin: 5px;
}

使用生成内容作为浮动项

在上面的示例中,我们使用了图像或可见元素来定义形状,这意味着你可以在页面上看到该形状。但有时,你可能希望让一些文本沿着一条不可见的非矩形线条流动。例如,我们可以在 DOM 中添加一个空的浮动 <div><span> 元素并使其不可见。然而,我们可以仅使用 CSS 和生成内容来创建一个形状,并将所有样式功能保留在 CSS 中。

在此示例中,我们使用生成内容插入了一个高度和宽度均为 150px 的元素。然后,我们可以使用基本形状、盒子值,甚至图像的 Alpha 通道来创建一个供文本环绕的形状。

html
<div class="box">
  <p>
    One November night in the year 1782, so the story runs, two brothers sat
    over their winter fire in the little French town of Annonay, watching the
    grey smoke-wreaths from the hearth curl up the wide chimney. Their names
    were Stephen and Joseph Montgolfier, they were papermakers by trade, and
    were noted as possessing thoughtful minds and a deep interest in all
    scientific knowledge and new discovery. Before that night—a memorable night,
    as it was to prove—hundreds of millions of people had watched the rising
    smoke-wreaths of their fires without drawing any special inspiration from
    the fact.
  </p>
</div>
css
body {
  font: 1.2em sans-serif;
}

.box::before {
  content: "";
  display: block;
  height: 150px;
  width: 150px;
  padding: 20px;
  margin: 20px;
  border-radius: 50%;
  float: left;
  shape-outside: border-box;
}

clip-path 的关系

用于创建形状的基本形状和盒子值与用作 clip-path 值的那些相同。因此,如果你想使用图像创建一个形状,并同时裁剪掉该图像的一部分,你可以使用相同的值。

下图是一张带有蓝色背景的正方形图像。我们使用 shape-outside: ellipse(40% 50%); 定义了一个形状,并使用 clip-path: ellipse(40% 50%); 裁剪掉了我们用于定义形状的相同区域。

html
<div class="box">
  <img
    alt="An orange hot air balloon as seen from below"
    src="https://mdn.github.io/shared-assets/images/examples/balloon-small.jpg" />
  <p>
    One November night in the year 1782, so the story runs, two brothers sat
    over their winter fire in the little French town of Annonay, watching the
    grey smoke-wreaths from the hearth curl up the wide chimney. Their names
    were Stephen and Joseph Montgolfier, they were papermakers by trade, and
    were noted as possessing thoughtful minds and a deep interest in all
    scientific knowledge and new discovery. Before that night—a memorable night,
    as it was to prove—hundreds of millions of people had watched the rising
    smoke-wreaths of their fires without drawing any special inspiration from
    the fact.
  </p>
</div>
css
body {
  font: 1.2em / 1.4 sans-serif;
}

img {
  float: left;
  shape-outside: ellipse(40% 50%);
  clip-path: ellipse(40% 50%);
}

用于形状的开发者工具

Firefox 开发者工具中有一个形状路径编辑器。此工具可用于检查 circle()inset()ellipse()polygon() 的值。如果你的多边形不太对,你可以使用形状编辑器对其进行调整,然后将新值复制回你的 CSS 中。

更多 CSS 形状特性

在本指南中,我们讨论了如何使文本环绕浮动形状。请参阅 CSS 形状模块以获取该模块所有特性以及其他相关特性的链接。这包括所有形状函数和相关指南。