1. 简介
本节不具有规范性。
形状定义了可用作 CSS 值的任意几何体。本规范定义了用于控制元素浮动区域几何形状的属性。shape-outside 属性使用形状值来定义浮动元素的浮动区域。
注意: 未来版本的 CSS 形状将允许在非浮动元素上使用形状。其他 CSS 模块也可以利用这些形状,例如 CSS 遮罩 [CSS-MASKING] 和 CSS 排除 [CSS3-EXCLUSIONS]。
注意: 如果用户代理同时实现了 CSS 形状和 CSS 排除,则 shape-outside 属性将定义排除元素的排除区域。
注意: 未来版本的 CSS 形状将定义 shape-inside 属性,用于定义元素内部内容的环绕形状。
1.1. 模块交互
本模块扩展了 [CSS2] 第 9 章中定义的浮动特性。
1.2. 值
本规范遵循 [CSS2] 中的 CSS 属性定义约定,并使用 [CSS-VALUES-3] 中的 值定义语法。本规范中未定义的值类型在 CSS Values & Units [CSS-VALUES-3] 中定义。与其他 CSS 模块的组合可能会扩展这些值类型的定义。
除了定义中列出的属性特定值外,本规范中定义的所有属性也都接受 CSS 全局关键字 作为其属性值。为了可读性,未明确重复列出。
1.3. 术语
折行
本规范使用术语环绕 (wrap) 来指代内容围绕 [CSS2] 第 9 章定义的浮动区域侧面流动的行为。内容在左浮动盒子的右侧环绕,在右浮动盒子的左侧环绕。这种环绕的结果是,浮动元素旁边的行框会根据需要缩短,以避免与浮动区域相交。
浮动区域
用于围绕浮动元素环绕内容的区域。浮动行为规则使用浮动区域的侧边来确定内容的流动位置。默认情况下,浮动区域是浮动元素的外边距框(注意,这可能不同于由 margin-box 值产生的浮动区域,后者包含边框半径曲率)。本规范的 shape-outside 和 shape-margin 属性可用于定义任意的、非矩形的浮动区域。
与方向无关的尺寸 盒子的与方向无关的尺寸等于该盒子的对角线长度除以 sqrt(2)。
注意: 这是一种在某些情况下 SVG 使用的平均化盒子宽高的方法,当需要盒子尺寸的百分比但上下文不特别偏向宽度或高度时使用。对于正方形盒子,这等同于宽度/高度。
2. 与盒模型和浮动行为的关系
虽然用于环绕浮动元素外部行内流内容的边界可以使用形状来定义,但实际的盒模型不会改变。如果元素指定了外边距、边框或内边距,它们将根据 [CSS3BOX] 模块进行计算和渲染。此外,浮动定位和堆叠不受定义带有形状的浮动区域的影响。
当形状用于定义浮动区域时,该形状会被剪裁至浮动的 margin box。换句话说,形状只能缩小浮动区域,而不能增加它。缩小的浮动区域可能对某些本应受浮动影响的行框没有影响。如果形状不封闭任何区域,形状的边缘仍被用于定义浮动区域。
由形状定义的浮动区域可以缩小所有侧面的正常浮动区域,但这并不允许内容在浮动的两侧环绕。左浮动且带有 shape-outside 的元素仍然只允许内容在右侧环绕,而右浮动元素则只允许在左侧环绕。
在以下示例中,左右浮动的 img 元素使用 shape-outside 属性指定了一个三角形形状。
<img class="left" src="hand.svg"/>
<img class="right" src="hand.svg"/>
<p>
Sometimes a web page’s text content appears to be
funneling your attention towards a spot on the page
to drive you to follow a particular link. Sometimes
you don’t notice.
</p>
<style type="text/css">
.left {
shape-outside: polygon(0 0, 100% 100%, 0 100%);
float: left;
width: 40%;
height: 12ex;
transform: scaleX(-1);
}
.right {
shape-outside: polygon(100% 0, 100% 100%, 0 100%);
float: right;
width: 40%;
height: 12ex;
}
p {
text-align: center;
}
</style>

不封闭任何区域的形状仍然具有有助于定义浮动区域的边缘。
此嵌入形状是一条位于参考框中点的垂直线。此中点边缘被用作环绕内容的浮动区域边缘。
shape-outside: inset(0% 50% 0% 50%);
如果嵌入值总和超过了宽度,则使用 CSS 背景 3 § 4.5 重叠曲线 规则来确定矩形的边缘。此形状产生一个距离参考框左侧 25% 的垂直边缘。
shape-outside: inset(0% 150% 50% 0%);
如果该形状仅是一条水平线,则它是一个空的浮动区域,对环绕没有影响。注意在此示例中 shape-margin 必须为 0px(否则该线会扩展以封闭一个区域)。
shape-outside: inset(50% 0% 0% 50%);
shape-margin: 0px;
shape-outside 可以在浮动区域的左侧和右侧都创建开放区域。在这种情况下,内容仍然只在浮动的一侧环绕。在图中,形状以蓝色渲染,形状外部的内容区域以紫红色渲染。
shape-outside: polygon(50px 0px, 100px 100px, 0px 100px);

以下样式创建了一个比浮动内容区域小得多的形状,并为浮动元素添加了 margin-top。在图中,形状以蓝色渲染,内容区域以紫红色渲染,浮动框的 margin 区域以黄色渲染。行内内容只环绕该形状,并在其他地方覆盖浮动 margin box 的其余部分。
.float-left {
shape-outside: polygon(0% 50%, 50% 100%, 0 100%);
float: left;
width: 100px;
height: 100px;
margin-top: 20px;
}

下一张图片展示了如果两个这样的浮动元素堆叠在一起时可能产生的结果。注意浮动元素是使用它们的 margin box 而不是浮动区域进行定位的。

3. 基本形状
<basic-shape> 类型可以使用基本形状函数来指定。当使用此语法定义形状时,参考框 (reference box) 由每个使用 <basic-shape> 值的属性定义。形状的坐标系原点位于参考框的左上角,x 轴向右延伸,y 轴向下延伸。所有以百分比表示的长度均基于参考框的使用尺寸进行解析。
3.1. 支持的形状
<basic-shape> 函数包括:
<inset()> = inset(
<length-percentage>{1,4}
[ round <'border-radius'> ]?
)
<xywh()> = xywh(
<length-percentage>{2} <length-percentage [0,∞]>{2}
[ round <'border-radius'> ]?
)
<rect()> = rect(
[ <length-percentage> | auto ]{4}
[ round <'border-radius'> ]?
)
<basic-shape-rect> = <inset()> | <rect()> | <xywh()>
<circle()> = circle(
<radial-size>?
[ at <position> ]?
)
<ellipse()> = ellipse(
<radial-size>?
[ at <position> ]?
)
<polygon()> = polygon(
<'fill-rule'>?
[ round <length> ]? ,
[<length-percentage> <length-percentage>]#
)
<path()> = path(
<'fill-rule'>? ,
<string>
)
<shape()> = shape(
<'fill-rule'>?
from <position>
<shape-command>#
)
- inset()
- 通过距参考框每个边缘的偏移量来定义一个内嵌矩形。
如果提供的 <length-percentage> 值少于四个,省略的值将遵循 margin 速记属性的默认方式:省略的第二或第三个值默认为第一个值,省略的第四个值默认为第二个值。
这四个 <length-percentage> 分别定义了矩形顶部、右侧、底部和左侧边缘的位置,作为相对于参考框对应边缘的内嵌偏移量。
在任一维度上,如果一对内嵌偏移量的总和超过了使用尺寸(例如左右内嵌各为 75%),则使用 CSS 背景 3 § 4.5 重叠曲线 规则,将内嵌效果比例缩小至 100%。
可选的 <'border-radius'> 参数定义了矩形的圆角,使用 border-radius 速记语法。
- xywh()
- 通过相对于参考框顶部和左侧边缘的偏移量以及指定的宽度和高度来定义矩形。
这四个 <length-percentage> 分别定义了相对于参考框左边缘的偏移量、相对于参考框顶边缘的偏移量、矩形的宽度以及矩形的高度。
注意: 此语法受 SVG 中
viewBox属性的启发。可选的 <'border-radius'> 参数定义了内嵌矩形的圆角,使用 border-radius 速记语法。
- rect() =
- 通过相对于参考框顶部和左侧边缘的内嵌偏移量来定义矩形。
这四个 <length-percentage> 分别定义了矩形顶部、右侧、底部和左侧边缘的位置,作为相对于参考框顶部边缘(对于第一个和第三个值)或参考框左侧边缘(对于第二个和第四个值)的内嵌偏移量。
auto 值使盒子的边缘与参考框的相应边缘重合:它等同于作为第一个(顶部)或第四个(左侧)值的 0%,以及作为第二个(右侧)或第三个(底部)值的 100%。
第二个(右侧)和第三个(底部)值会被第四个(左侧)和第二个(顶部)值下限约束。
例如,指定 rect(10px 0 0 20px) 会使底部边缘高于顶部边缘,右边缘位于左边缘的左侧,因此两者都会被修正为不跨越对方,这与指定 rect(10px 20px 10px 20px) 的效果相同。注意: 此语法与仅由 clip 属性使用的旧版 rect() 函数类似,但不完全相同。
可选的 <'border-radius'> 参数定义了矩形的圆角,使用 border-radius 速记语法。)
- circle()
-
-
<radial-size> 参数定义了圆的半径。这些值不是指渐变框,而是相对于参考框进行解析。
-
两个 <length-percentage> 值是无效的。
<position> 参数定义了圆心。除非另有说明,如果省略,默认为 center。
-
- ellipse()
-
-
<radial-size> 参数定义了椭圆的水平和垂直半径。这些值不是指渐变框,而是相对于参考框进行解析。
-
<position> 参数定义了椭圆的圆心。除非另有说明,如果省略,默认为 center。
-
- polygon()
-
-
<'fill-rule'> 指定用于确定内部的填充规则。如果省略,默认为 nonzero。
-
round 关键字后的可选 <length> 定义了多边形每个顶点的圆角。该长度是一个圆的半径,其圆心位于顶点较小角度的平分线上,且与顶点的两条边相切。
为了避免对任何线段超过一半的部分进行圆角处理,每个顶点的圆角半径必须分别被钳制,使得半径永远不会超过根据两个顶点线段评估出的
tan(angle/2) segment / 2的较小值。 -
每对 <length-percentage> 指定了多边形的一个顶点,作为相对于参考框左侧和顶部边缘的水平和垂直偏移量。
用户代理必须通过连接最后一个顶点和列表中的第一个顶点来闭合多边形。
-
- path()
-
-
<'fill-rule'> 指定用于确定内部的填充规则。如果省略,默认为 nonzero,除非该函数被用于例如 SVG 形状等 fill-rule 属性相关的上下文中。在这种情况下,省略的值将使用 fill-rule 属性的计算值。
-
<string> 表示 SVG 路径数据字符串。不符合 SVG 1.1 语法和解析规则的路径数据字符串,或者符合但定义为空路径的字符串,是 无效的,并导致整个 path() 变为 无效。
初始位置由路径字符串中的第一个“移动到”参数定义。初始方向遵循 SVG 1.1。
对于需要闭合环的属性(例如 shape-outside 和 clip-path),如果字符串中不存在闭合路径命令(“z”或“Z”),用户代理必须以隐式闭合路径命令结束该路径。
-
- shape()
- 参见 shape() 函数。
测试
3.1.1. shape() 函数
虽然 path() 函数允许重用 SVG 路径语法来定义比专用形状函数更随意的形状,但它要求将路径编写为单个字符串(例如,这与使用 var() 逐块构建路径不兼容),并且从 SVG 继承了许多限制,例如隐式仅允许 px 单位。
shape() 函数使用的一组命令大致等同于 path() 所使用的命令,但使用了更标准的 CSS 语法,并允许完整的 CSS 功能范围,例如额外的单位和数学函数。shape() 使用的命令在用于渲染(例如,计算渲染的 clip-path 时)会动态转换为路径段。
从这个意义上讲,shape() 是 path() 的超集。path() 可以轻松转换为 shape(),但要将 shape() 转回 path() 或 SVG,则需要有关 CSS 环境的信息(例如 CSS 自定义属性的当前值、em 单位的当前字体大小等)。
<'fill-rule'> 的解释与 path() 中的同名参数相同。
其余参数定义了一系列路径数据命令,等同于该函数所代表的 SVG 路径。
from <coordinate-pair> 表示第一个形状命令的起点。它会在路径数据命令列表中添加一个初始的 绝对移动到 (absolute moveto) 命令。
<shape-command> 序列表示进一步的 路径数据命令。每个命令的起点是前一个命令的终点。
<shape-command> = <move-command> | <line-command> | close |
<horizontal-line-command> | <vertical-line-command> |
<curve-command> | <smooth-command> | <arc-command>
<move-command> = move <command-end-point>
<line-command> = line <command-end-point>
<horizontal-line-command> = hline
[ to [ <length-percentage> | left | center | right | x-start | x-end ]
| by <length-percentage> ]
<vertical-line-command> = vline
[ to [ <length-percentage> | top | center | bottom | y-start | y-end ]
| by <length-percentage> ]
<curve-command> = curve
[ [ to <position> with <control-point> [ / <control-point> ]? ]
| [ by <coordinate-pair> with <relative-control-point> [ / <relative-control-point> ]? ] ]
<smooth-command> = smooth
[ [ to <position> [ with <control-point> ]? ]
| [ by <coordinate-pair> [ with <relative-control-point> ]? ] ]
<arc-command> = arc <command-end-point>
[ [ of <length-percentage>{1,2} ]
&& <arc-sweep>? && <arc-size>? && [rotate <angle>]? ]
<command-end-point> = [ to <position> | by <coordinate-pair> ]
<control-point> = [ <position> | <relative-control-point> ]
<relative-control-point> = <coordinate-pair> [ from [ start | end | origin ] ]?
<coordinate-pair> = <length-percentage>{2}
<arc-sweep> = cw | ccw
<arc-size> = large | small
- <coordinate-pair> = <length-percentage>{2}
- 定义一对坐标,分别表示相对于指定参考点的向右和向下偏移量。百分比基于参考框的宽度或高度进行解析。
- <command-end-point> = [ to <position> | by <coordinate-pair> ]
- 每个命令都可以以“绝对”或“相对”坐标指定,这由其 by 或 to 组件决定。to 表示命令中的任何 <coordinate-pair> 都是相对于参考框的左上角,而 by 表示 <coordinate-pair> 是相对于命令的起点。
<relative-control-point> 定义了曲线控制点如何解释 by 和 to,而 <horizontal-line-command> 和 <vertical-line-command> 分别定义了如何为水平和垂直线解释 by 和 to。
当使用 to 时,坐标可以指定为 <position> 而不是 <coordinate-pair>。
注意: 在这两种情况下,<coordinate-pair> 中的 <percentage> 值始终根据参考框的大小进行计算。
- <move-command> = move <command-end-point>
- 向路径数据命令列表添加一个 moveto 命令,终点由 <coordinate-pair> 指定。
这不会绘制任何东西,仅仅是为下一个命令“移动笔”。
注意: 这会开始一个新的子路径,用于 close 命令。
- <line-command> = line <command-end-point>
- 向路径数据命令列表添加一个 lineto 命令,终点由 <coordinate-pair> 指定。
这会从命令的起点到其终点绘制一条直线。
- <horizontal-line-command> = hline [ to [ <length-percentage> | left | center | right | x-start | x-end ] | by <length-percentage> ]
- 向路径数据命令列表添加一个水平 lineto 命令。
这等同于一个 line 命令,其中 <length-percentage> 作为 <coordinate-pair> 的水平组件给出。指定 <position> 的水平组件而不是 <length-percentage>(left、center、right、x-start 或 x-end)将绘制一条到该 <position> 的线,其中 <position> 的垂直组件与起点相同。
- <vertical-line-command> = vline [ to [ <length-percentage> | top | center | bottom | y-start | y-end ] | by <length-percentage> ]
- 向路径数据命令列表添加一个垂直 lineto 命令。
这等同于一个 line 命令,其中 <length-percentage> 作为 <coordinate-pair> 的垂直组件给出。指定 <position> 的垂直组件(top、center、bottom、y-start 或 y-end)而不是 <length-percentage> 将绘制一条到该 <position> 的线,其中 <position> 的水平组件与起点相同。
- <curve-command> = curve [ [ to <position> with <control-point> [ / <control-point> ]? ] | [ by <coordinate-pair> with <relative-control-point> [ / <relative-control-point> ]? ] ]
- 向路径数据命令列表添加一个贝塞尔曲线命令,终点由 to 关键字后的 <position> 或 by 关键字后的 <coordinate-pair> 指定。
with 组件指定曲线的控制点:如果提供一个 <control-point> 或 <relative-control-point>,则命令指定一个 二次曲线;如果提供两个控制点,则指定一个 三次曲线。
- <smooth-command> = smooth [ [ to <position> [with <control-point> ]? ] | [ by <coordinate-pair> [ with <relative-control-point> ]? ] ]
- 向路径数据命令列表添加一个平滑贝塞尔曲线命令,终点由 to 关键字后的 <position> 或 by 关键字后的 <coordinate-pair> 指定。with 组件指定曲线的控制点:如果省略,命令指定一个 平滑二次曲线;如果提供,则指定一个 平滑三次曲线。
注意: smooth 命令等同于 curve 命令,其中第一个控制点自动指定为前一个曲线的第二个控制点围绕起点的反射点,或者如果前一个路径数据命令不是曲线,则为起点。这确保了与前一个命令的 G1 连续性,因此曲线看起来是从前一个命令平滑继续的,而不是突然改变方向。
- <control-point> = [ <position> | <relative-control-point> ]
- 为二次或三次贝塞尔曲线提供控制点。
- <relative-control-point> = <coordinate-pair> [ from [ start | end | origin ] ]?
- 为二次或三次贝塞尔曲线提供控制点。当指定 from 关键字后跟 start、end 或 origin 时,给定的 <coordinate-pair> 分别相对于命令的起点、命令的终点或参考框。如果没有提供此类组件,则 <coordinate-pair> 相对于段的起点。
- <arc-command> = arc <command-end-point> [of <length-percentage>{1,2}] && <arc-sweep>? && <arc-size>? && rotate <angle>? ]
- 向路径数据命令列表添加一个 椭圆弧 命令,终点为 <command-end-point>。
of 组件指定弧线所属椭圆的尺寸。第一个 <length-percentage> 提供椭圆的水平半径,第二个提供垂直半径。与 <coordinate-pair> 一样,<percentage> 值根据参考框的宽度或高度进行解析。
如果仅提供一个 <length-percentage>,则两个半径均使用该值。在这种情况下,<percentage> 值根据参考框的与方向无关的尺寸进行解析(类似于 circle() 函数)。
注意 SVG 对椭圆半径有一些特定的错误处理-
如果终点与起点相同,则该命令不执行任何操作
-
如果任一半径为零,则该命令等同于到终点的 <line-command>
-
如果任一半径为负,则使用其绝对值
-
如果半径描述的椭圆不足以同时通过起点和终点(在指定 <angle> 旋转后),它们将被均匀放大,直到椭圆刚好足够大。
由指定半径描述的椭圆默认为轴对齐,但可以通过指定 <angle> 进行旋转。类似于 rotate() 变换函数,正角度指定顺时针旋转,负角度指定逆时针旋转。如果省略,默认为 0deg。
终点、半径和角度结合在一起,通常定义了两个通过起点和终点的可能椭圆,每个椭圆可以在任一方向上跟踪,总共四个可能的弧线。<arc-sweep> 和 <arc-size> 组件指定需要其中的哪一个弧线
-
<arc-sweep> 可以是 cw 或 ccw,分别表示必须选择围绕中心顺时针或逆时针跟踪的弧线。如果省略,默认为 ccw。
注意: 在 SVG 弧命令中,cw 对应于扫描标志 (sweep flag) 的值 1,而 ccw 对应于值 0。
-
<arc-size> 可以是 large 或 small,分别表示必须选择两个可能的弧线中较大或较小的一个。如果省略,默认为 small。
注意: 在 SVG 弧命令中,large 对应于大标志 (large flag) 的值 1,而 small 对应于 0。
注意: 如果起点和终点位于椭圆的正对面,则两个可能的弧线大小相同,但也只有一个可能的椭圆。在这种情况下,<arc-sweep> 区分选择哪一个可能的弧线,而 <arc-size> 不起作用。
两个可能椭圆的描绘,以及在两者之间可以选择的四个可能的弧线。 -
- 关闭
- 向路径数据命令列表添加一个 closepath 命令。
注意: 这类似于一个 line 命令,其终点设置为子路径的起点。当指定原始形状时,它们是相同的,但如果路径被描边,close 命令的终点会与子路径的起点平滑连接,这会影响线连接和线帽的渲染方式。
3.1.1.1. 使用 shape() 创建响应式、参数化的对话气泡
为了演示,让我们从一个对话气泡开始,如下所示
将此形状与 clip-path 一起使用可以通过 path() 函数完成
.bubble{ clip-path : path ( "m 5 0 H 95 Q 100 0 100 5 V 92 Q 100 97 95 97 H 70 l -2 3 l -2 -3 H 5 Q 0 97 0 92 V 5 Q 0 0 5 0" ) };
虽然此路径可以轻松缩放,但缩放后的结果并不总是理想的。例如,缩放到小气球时,箭头和圆角会缩放到几乎不可见
要使用 shape() 函数构建此形状,让我们首先将 path 函数中的所有像素值转换为百分比。注意 shape() 函数以 from 开头
.bubble{ clip-path : shape ( from5 % 0 % , hline to95 % , curve to100 % 5 % with100 % 0 % , vline to92 % , curve to95 % 97 % with100 % 97 % , hline to70 % , line by-2 % 3 % , line by-2 % -3 % , hline to5 % , curve to0 % 92 % with0 % 97 % , vline to5 % , curve to5 % 0 % with0 % 0 % ); }
为了使该路径具有响应性(即对尺寸变化有良好的响应),我们将把部分单位转换为 px 值,特别是那些控制曲线和箭头的单位
.bubble{ clip-path : shape ( from5 px 0 % , hline tocalc ( 100 % -5 px ), curve to100 % 5 px with100 % 0 % , vline tocalc ( 100 % -8 px ), curve tocalc ( 100 % -5 px ) calc ( 100 % -3 px ) with100 % calc ( 100 % -3 px ), hline to70 % , line by-2 px 3 px , line by-2 px -3 px , hline to5 px , curve to0 % calc ( 100 % -8 px ) with0 % calc ( 100 % -3 px ), vline to5 px , curve to5 px 0 % with0 % 0 % ); }
当作为 clip-path 应用时,它看起来如下所示
整个对话气泡会缩放到参考框,而曲线和箭头保持相对固定。
由于 shape() 使用 CSS 单位,我们可以用 position 值替换一些边缘
.bubble{ clip-path : shape ( from5 px 0 , hline tocalc ( 100 % -5 px ), curve to right5 px with right top, vline tocalc ( 100 % -8 px ), curve tocalc ( 100 % -5 px ) calc ( 100 % -3 px ) with rightcalc ( 100 % -3 px ), hline to70 % , line by-2 px 3 px , line by-2 px -3 px , hline to5 px , curve to leftcalc ( 100 % -8 px ) with leftcalc ( 100 % -3 px ), vline to5 px , curve to5 px top with left top); }
shape() 的另一个有用特性是它可以与 CSS 属性一起使用。在这种情况下,我们可以使箭头和半径参数化
:root{ --radius : 5 px ; --arrow-length : 3 px ; --arrow-half-width : 2 px ; --arrow-position : 70 % ; --arrow-bottom-offset : calc ( 100 % -var ( --radius) -var ( --arrow-length)); } .bubble{ animation : bubble100 ms ; clip-path : shape ( fromvar ( ---radius) top, hline tocalc ( 100 % -var ( ---radius)), curve to rightvar ( ---radius) with right top, vline tovar ( ---arrow-bottom-offset), curve tocalc ( 100 % -var ( ---radius)) calc ( 100 % -var ( ---arrow-length)) with rightcalc ( 100 % -var ( ---arrow-length)), hline tovar ( ---arrow-position), line byvar ( ---arrow-half-width) var ( ---arrow-length), line byvar ( ---arrow-half-width) calc ( 0 px -var ( ---arrow-length)), hline tovar ( ---radius), curve to leftvar ( ---arrow-bottom-offset) with leftcalc ( 100 % -var ( ---arrow-length)), vline tovar ( ---radius), curve tovar ( ---radius) top with left top); }
3.1.1.2. shape() 函数的插值
shape() 和 path() 函数如果其相关路径数据命令列表长度相同且命令顺序相同,则可以互相插值,其中 path() 函数的第一个命令与 shape() 函数中的初始 <coordinate-pair> 进行插值。
注意: path() 函数的第一个命令保证是一个 move,参见 SVG 规范中的 moveTo。
如果起点和终点值都是 path() 函数,则插值结果是一个 path() 函数;否则它是一个 shape() 函数。在这两种情况下,插值后的值必须表示相同的路径数据命令列表,每个命令的数值组件在起始列表和结束列表的对应组件之间进行插值。
为此,如果命令使用相同的命令关键字和相同的 <by-to> 关键字,则它们是“相同”的。对于 curve 和 smooth,它们还必须具有相同数量的控制点。
如果一个 arc 命令在其起始列表和结束列表之间具有不同的 <arc-sweep>,则插值结果对于 0 和 1 之间的任何进度值使用 cw。如果它具有不同的 <arc-size> 关键字,则插值结果对于 0 和 1 之间的任何进度值使用 large。
注意: arc 关键字插值规则旨在匹配现有的 SVG path 插值规则。
3.2. 基本形状的计算值
<basic-shape> 函数中的值按指定方式计算,但有以下例外:
- 省略的值会被包含并计算为它们的默认值。
- circle() 或 ellipse() 中的 <position> 值被计算为相对于左上角原点的一对偏移量(先水平后垂直),每个均以 <length-percentage> 给出。
- <basic-shape-rect> 函数中的 <'border-radius'> 值被计算为所有八个 <length-percentage> 值的扩展列表。
- 所有 <basic-shape-rect> 函数都计算为等效的 inset() 函数。
注意: 给定 rect(t r b l),等效函数为 inset(t calc(100% - r) calc(100% - b) l)。给定 xywh(x y w h),等效函数为 inset(y calc(100% - x - w) calc(100% - y - h) x)。
测试
- shape-image-threshold-computed.html (在线测试) (源代码)
- shape-margin-computed.html (在线测试) (源代码)
- shape-outside-computed.html (在线测试) (源代码)
- circle-function-computed.html (在线测试) (源代码)
- ellipse-function-computed.html (在线测试) (源代码)
- inset-function-computed.html (在线测试) (源代码)
- path-function-computed.html (在线测试) (源代码)
- polygon-function-computed.html (在线测试) (源代码)
- rect-function-computed.html (在线测试) (源代码)
- xywh-function-computed.html (在线测试) (源代码)
- shape-outside-computed-shape-000.html (在线测试) (源代码)
- shape-outside-computed-shape-001.html (在线测试) (源代码)
3.3. 基本形状的序列化
要序列化 <basic-shape> 函数,请根据其各自的语法进行序列化,顺序与语法编写顺序一致,用单个空格连接空格分隔的标记,并在每个序列化逗号后跟一个空格。对于序列化计算值,分量值会计算,并在不改变含义的情况下尽可能省略。
由于形状函数的指定值序列化相对简单,以下是一些在 shape-outside 中使用时 circle() 标记的计算值序列化示例
-
<position> 序列化规则意味着关键字计算为百分比,并按水平-垂直顺序序列化。
circle(at bottom left) /* serializes to */ circle(at 0% 100%) -
省略可选组件意味着默认值不会显示在序列化中。
circle(closest-side at center) /* serializes to */ circle() -
rect(10px 20px 30px 40px) /* serializes to */ inset(10px calc(100% - 20px) calc(100% - 30px) 40px)
3.4. 基本形状的插值
对于在一个基本形状和第二个基本形状之间进行插值,应用以下规则。形状函数中的值按计算值进行插值。列表值在可能的情况下按长度、百分比或 calc 进行插值。如果列表值不是这些类型之一但相同(例如在两个列表中发现相同列表位置的 nonzero),这些值会进行插值。
- 两个形状必须使用相同的参考框。
- 如果两个形状类型相同,且该类型为 ellipse() 或 circle(),且半径指定为 <length-percentage>(而不是关键字),则在形状函数中的每个值之间进行插值。
- 如果两个形状的类型均为 inset(),则在形状函数中的每个值之间进行插值。
- 如果两个形状的类型均为 polygon(),且两个多边形具有相同的顶点数并使用相同的 <'fill-rule'>,则在形状函数中的每个值之间进行插值。
- 在所有其他情况下,未指定插值。
测试
4. 基于图像的形状 (Shapes from Image)
定义形状的另一种方法是指定一个源 <image>,利用其 Alpha 通道来计算形状。计算得出的形状是包围了指定图像不透明度大于 shape-image-threshold 值区域的路径。如果不存在 Alpha 值大于指定阈值的像素,则会导致浮动区域为空,从而不会影响环绕排版。如果未指定 shape-image-threshold,则考虑的初始值为 0.0。
图像的尺寸和位置设定如同一个替换元素,其指定的宽度和高度与该元素的已用内容框 (content box) 尺寸相同。
对于动画光栅图像格式(如 GIF),将使用动画序列的第一帧。
图像浮动在段落左侧。该图像显示了透明背景上的 CSS 徽标 3D 版本。徽标利用 Alpha 通道带有一层阴影。
图像通过 shape-outside 属性定义其 浮动区域。
<p>
<img id="CSSlogo" src="CSS-logo1s.png"/>
blah blah blah blah...
</p>
<style>
#CSSlogo {
float: left;
shape-outside: attr(src url);
shape-image-threshold: 0.1;
}
</style>
shape-outside 属性复用了 img 元素 src 属性中的 url。
完全可以显示一张图像,并为其 浮动区域 使用另一张不同的图像。
在下图中,Alpha 通道阈值由 CSS 徽标周围的虚线表示。
通过以下三种方式可以影响段落行开始的位置:
- 修改图像中的 Alpha 通道
- 更改 shape-image-threshold 属性的值
- 更改 shape-margin 属性的值(参见示例 8)
测试
- shape-image-threshold-interpolation.html (在线测试) (源代码)
- shape-image-threshold-computed.html (在线测试) (源代码)
- shape-image-threshold-invalid.html (在线测试) (源码)
- shape-image-threshold-valid.html (在线测试) (源码)
- float-retry-push-image.html (在线测试) (源码)
- shape-outside-linear-gradient-001.html (在线测试) (源码)
- shape-outside-linear-gradient-002.html (在线测试) (源码)
- shape-outside-linear-gradient-003.html (在线测试) (源码)
- shape-outside-linear-gradient-004.html (在线测试) (源码)
- shape-outside-linear-gradient-005.html (在线测试) (源码)
- shape-outside-linear-gradient-006.html (在线测试) (源码)
- shape-outside-linear-gradient-007.html (在线测试) (源码)
- shape-outside-linear-gradient-008.html (在线测试) (源码)
- shape-outside-linear-gradient-009.html (在线测试) (源码)
- shape-outside-linear-gradient-010.html (在线测试) (源码)
- shape-outside-linear-gradient-011.html (在线测试) (源码)
- shape-outside-linear-gradient-012.html (在线测试) (源码)
- shape-outside-linear-gradient-013.html (在线测试) (源码)
- shape-outside-linear-gradient-014.html (在线测试) (源码)
- shape-outside-linear-gradient-015.html (在线测试) (源码)
- shape-outside-linear-gradient-016.html (在线测试) (源码)
- shape-outside-radial-gradient-001.html (在线测试) (源码)
- shape-outside-radial-gradient-002.html (在线测试) (源码)
- shape-outside-radial-gradient-003.html (在线测试) (源码)
- shape-outside-radial-gradient-004.html (在线测试) (源码)
- shape-image-000.html (在线测试) (源码)
- shape-image-001.html (在线测试) (源码)
- shape-image-002.html (在线测试) (源码)
- shape-image-003.html (在线测试) (源码)
- shape-image-004.html (在线测试) (源码)
- shape-image-005.html (在线测试) (源码)
- shape-image-006.html (在线测试) (源码)
- shape-image-007.html (在线测试) (源码)
- shape-image-008.html (在线测试) (源码)
- shape-image-009.html (在线测试) (源码)
- shape-image-010.html (在线测试) (源码)
- shape-image-011.html (在线测试) (源码)
- shape-image-012.html (在线测试) (源码)
- shape-image-013.html (在线测试) (源码)
- shape-image-014.html (在线测试) (源码)
- shape-image-015.html (在线测试) (源码)
- shape-image-016.html (在线测试) (源码)
- shape-image-017.html (在线测试) (源码)
- shape-image-018.html (在线测试) (源码)
- shape-image-019.html (在线测试) (源码)
- shape-image-020.html (在线测试) (源码)
- shape-image-021.html (在线测试) (源码)
- shape-image-022.html (在线测试) (源码)
- shape-image-023.html (在线测试) (源码)
- shape-image-024.html (在线测试) (源码)
- shape-image-025.html (在线测试) (源码)
- shape-image-026.html (在线测试) (源码)
- shape-image-027.html (在线测试) (源码)
- shape-image-028.html (在线测试) (源码)
- shape-image-029.html (在线测试) (源码)
5. 基于框值的形状 (Shapes from Box Values)
形状可以通过引用 CSS 盒模型 中的边来定义。这些边包括来自已用 border-radius 值的 边框圆角曲率 [CSS3BG]。<shape-box> 值扩展了 <visual-box> 值,增加了 margin-box。其语法为
<shape-box> = <visual-box> | margin-box
这些值的定义如下
margin-box 值定义了由外部外边距边缘包围的形状。该形状的圆角半径由相应的 border-radius 和 margin 值决定。如果 border-radius/margin 的比例为 1 或以上,或者 margin 为负数或零,则外边距框的圆角半径为 max(border-radius + margin, 0)。如果 border-radius/margin 的比例小于 1,且 margin 为正数,则外边距框的圆角半径为 border-radius + margin * (1 + (ratio-1)^3)。
border-box 值定义了由外部边框边缘包围的形状。该形状遵循所有正常的边框外部圆角形状规则。
padding-box 值定义了由外部内边距边缘包围的形状。该形状遵循所有正常的边框内部圆角形状规则。
content-box 值定义了由外部内容边缘包围的形状。此框的每个圆角半径为 0 或 border-radius - border-width - padding 中的较大者。
给定下方具有 10px 内边距、边框和外边距的 100px 正方形,框值定义了这些形状
- margin-box:包含所有黄色像素的形状
- border-box:包含所有黑色像素的形状
- padding-box:包含所有紫红色像素的形状
- content-box:包含所有蓝色像素的形状
相同的定义也适用于更复杂的例子:同样是 100px 的正方形,但具有这些边框、内边距和外边距属性
border-radius: 20px 20px 20px 40px;
border-width: 30px 10px 20px 10px;
padding: 10px 20px 10px 10px;
margin: 20px 10px 10px 10px;
普通浮动环绕与基于 margin-box 值定义的形状环绕之间的区别在于,margin-box 形状包含了圆角处理。以具有 10px 内边距、边框和外边距的 100px 正方形为例,但设置 border-radius 为 60px。如果将其设为左浮动,内容通常会以这种方式环绕
如果你为浮动添加一个 margin-box 形状,则内容会环绕圆角后的 margin-box 角。
shape-outside: margin-box;
测试
- shape-outside-border-box-001.html (在线测试) (源码)
- shape-outside-border-box-002.html (在线测试) (源码)
- shape-outside-border-box-003.html (在线测试) (源码)
- shape-outside-border-box-border-radius-001.html (在线测试) (源码)
- shape-outside-border-box-border-radius-002.html (在线测试) (源码)
- shape-outside-border-box-border-radius-003.html (在线测试) (源码)
- shape-outside-border-box-border-radius-004.html (在线测试) (源码)
- shape-outside-border-box-border-radius-005.html (在线测试) (源码)
- shape-outside-border-box-border-radius-006.html (在线测试) (源码)
- shape-outside-border-box-border-radius-007.html (在线测试) (源码)
- shape-outside-border-box-border-radius-008.html (在线测试) (源码)
- shape-outside-border-box-border-radius-009.html (在线测试) (源码)
- shape-outside-border-box-border-radius-010.html (在线测试) (源码)
- shape-outside-border-box-border-radius-011.html (在线测试) (源码)
- shape-outside-border-box-border-radius-012.html (在线测试) (源码)
- shape-outside-box-002.html (在线测试) (源码)
- shape-outside-box-003.html (在线测试) (源码)
- shape-outside-box-004.html (在线测试) (源码)
- shape-outside-box-006.html (在线测试) (源码)
- shape-outside-box-007.html (在线测试) (源码)
- shape-outside-box-008.html (在线测试) (源码)
- shape-outside-box-009.html (在线测试) (源码)
- shape-outside-content-box-001.html (在线测试) (源码)
- shape-outside-content-box-002.html (在线测试) (源码)
- shape-outside-content-box-003.html (在线测试) (源码)
- shape-outside-content-box-border-radius-001.html (在线测试) (源码)
- shape-outside-content-box-border-radius-002.html (在线测试) (源码)
- shape-outside-margin-box-001.html (在线测试) (源码)
- shape-outside-margin-box-002.html (在线测试) (源码)
- shape-outside-margin-box-border-radius-001.html (在线测试) (源码)
- shape-outside-margin-box-border-radius-002.html (在线测试) (源码)
- shape-outside-margin-box-border-radius-003.html (在线测试) (源码)
- shape-outside-margin-box-border-radius-004.html (在线测试) (源码)
- shape-outside-margin-box-border-radius-005.html (在线测试) (源码)
- shape-outside-margin-box-border-radius-006.html (在线测试) (源码)
- shape-outside-margin-box-border-radius-007.html (在线测试) (源码)
- shape-outside-margin-box-border-radius-008.html (在线测试) (源码)
- shape-outside-padding-box-001.html (在线测试) (源码)
- shape-outside-padding-box-002.html (在线测试) (源码)
- shape-outside-padding-box-003.html (在线测试) (源码)
- shape-outside-padding-box-border-radius-001.html (在线测试) (源码)
- shape-outside-padding-box-border-radius-002.html (在线测试) (源码)
- shape-outside-box-000.html (在线测试) (源码)
- shape-outside-shape-box-pair-000.html (在线测试) (源码)
6. 声明形状 (Declaring Shapes)
形状通过 shape-outside 属性声明,并可能受到 shape-margin 属性的修改。由 shape-outside 和 shape-margin 属性定义的形状会改变浮动元素的 浮动区域 的几何结构。
6.1. 浮动区域形状:shape-outside 属性
| 名称 | shape-outside |
|---|---|
| 值 | none | [ <basic-shape> || <shape-box> ] | <image> |
| 初始值 | none(无) |
| 应用于 | 浮动元素和 首字母框 |
| 可继承 | 否 |
| 百分比 | 不可用 |
| 计算值 | 按 <basic-shape> 的 定义(如果提供,则紧跟 <shape-box>);否则为计算后的 <image>;否则为指定的关键字 |
| 规范顺序 | 按语法 |
| 动画类型 | 按 <basic-shape> 的 定义,否则为离散值 |
该属性的取值含义如下
- none(无)
- 浮动区域 不受影响。
- <shape-box>
- 如果单独指定其中一个值,则形状基于 margin-box、border-box、padding-box 或 content-box 之一进行计算,这些值会使用它们各自包含 border-radius 曲率的框,类似于 background-clip [CSS3BG]。
- <basic-shape>
- 形状基于 <basic-shape> 函数之一进行计算。如果同时提供了 <shape-box>,则它定义了 参考框 用于 <basic-shape> 函数。如果未提供 <shape-box>,则 参考框 默认为 margin-box。
- <image>
- 形状根据 shape-image-threshold 的定义,基于指定 <image> 的 Alpha 通道提取并计算。
对于 shape-outside 值中的所有 URL,用户代理必须使用 [FETCH] 规范定义的 CORS 协议。在获取时,用户代理必须使用“匿名 (Anonymous)”模式,将 Referer 源设置为样式表的 URL,并将 Origin 设置为包含该文档的 URL。如果这导致网络错误以至于没有有效的后备图像,则其效果如同指定了 none 值一样。
测试
- shape-outside-composition.html (在线测试) (源代码)
- shape-outside-interpolation.html (在线测试) (源代码)
- inheritance.html (在线测试) (源码)
- shape-outside-computed.html (在线测试) (源代码)
- shape-outside-invalid-position.html (在线测试) (源码)
- shape-outside-valid-position.html (在线测试) (源码)
- shape-outside-infinite-crash.html (在线测试) (源码)
- shape-outside-invalid-001.html (在线测试) (源码)
- shape-outside-invalid-circle-000.html (在线测试) (源码)
- shape-outside-invalid-circle-001.html (在线测试) (源码)
- shape-outside-invalid-circle-002.html (在线测试) (源码)
- shape-outside-invalid-circle-003.html (在线测试) (源码)
- shape-outside-invalid-ellipse-001.html (在线测试) (源码)
- shape-outside-invalid-ellipse-002.html (在线测试) (源码)
- shape-outside-invalid-ellipse-003.html (在线测试) (源码)
- shape-outside-invalid-ellipse-004.html (在线测试) (源码)
- shape-outside-invalid-ellipse-005.html (在线测试) (源码)
- shape-outside-invalid-ellipse-006.html (在线测试) (源码)
- shape-outside-invalid-inset-001.html (在线测试) (源码)
- shape-outside-invalid-inset-002.html (在线测试) (源码)
- shape-outside-invalid-inset-003.html (在线测试) (源码)
- shape-outside-invalid-inset-004.html (在线测试) (源码)
- float-retry-push-circle.html (在线测试) (源码)
- float-retry-push-image.html (在线测试) (源码)
- float-retry-push-inset.html (在线测试) (源码)
- float-retry-push-polygon.html (在线测试) (源码)
- float-should-push.html (在线测试) (源码)
- shape-outside-border-box-001.html (在线测试) (源码)
- shape-outside-border-box-002.html (在线测试) (源码)
- shape-outside-border-box-003.html (在线测试) (源码)
- shape-outside-border-box-border-radius-001.html (在线测试) (源码)
- shape-outside-border-box-border-radius-002.html (在线测试) (源码)
- shape-outside-border-box-border-radius-003.html (在线测试) (源码)
- shape-outside-border-box-border-radius-004.html (在线测试) (源码)
- shape-outside-border-box-border-radius-005.html (在线测试) (源码)
- shape-outside-border-box-border-radius-006.html (在线测试) (源码)
- shape-outside-border-box-border-radius-007.html (在线测试) (源码)
- shape-outside-border-box-border-radius-008.html (在线测试) (源码)
- shape-outside-border-box-border-radius-009.html (在线测试) (源码)
- shape-outside-border-box-border-radius-010.html (在线测试) (源码)
- shape-outside-border-box-border-radius-011.html (在线测试) (源码)
- shape-outside-border-box-border-radius-012.html (在线测试) (源码)
- shape-outside-box-002.html (在线测试) (源码)
- shape-outside-box-003.html (在线测试) (源码)
- shape-outside-box-004.html (在线测试) (源码)
- shape-outside-box-006.html (在线测试) (源码)
- shape-outside-box-007.html (在线测试) (源码)
- shape-outside-box-008.html (在线测试) (源码)
- shape-outside-box-009.html (在线测试) (源码)
- shape-outside-content-box-001.html (在线测试) (源码)
- shape-outside-content-box-002.html (在线测试) (源码)
- shape-outside-content-box-003.html (在线测试) (源码)
- shape-outside-content-box-border-radius-001.html (在线测试) (源码)
- shape-outside-content-box-border-radius-002.html (在线测试) (源码)
- shape-outside-margin-box-001.html (在线测试) (源码)
- shape-outside-margin-box-002.html (在线测试) (源码)
- shape-outside-margin-box-border-radius-001.html (在线测试) (源码)
- shape-outside-margin-box-border-radius-002.html (在线测试) (源码)
- shape-outside-margin-box-border-radius-003.html (在线测试) (源码)
- shape-outside-margin-box-border-radius-004.html (在线测试) (源码)
- shape-outside-margin-box-border-radius-005.html (在线测试) (源码)
- shape-outside-margin-box-border-radius-006.html (在线测试) (源码)
- shape-outside-margin-box-border-radius-007.html (在线测试) (源码)
- shape-outside-margin-box-border-radius-008.html (在线测试) (源码)
- shape-outside-padding-box-001.html (在线测试) (源码)
- shape-outside-padding-box-002.html (在线测试) (源码)
- shape-outside-padding-box-003.html (在线测试) (源码)
- shape-outside-padding-box-border-radius-001.html (在线测试) (源码)
- shape-outside-padding-box-border-radius-002.html (在线测试) (源码)
- shape-outside-linear-gradient-001.html (在线测试) (源码)
- shape-outside-linear-gradient-002.html (在线测试) (源码)
- shape-outside-linear-gradient-003.html (在线测试) (源码)
- shape-outside-linear-gradient-004.html (在线测试) (源码)
- shape-outside-linear-gradient-005.html (在线测试) (源码)
- shape-outside-linear-gradient-006.html (在线测试) (源码)
- shape-outside-linear-gradient-007.html (在线测试) (源码)
- shape-outside-linear-gradient-008.html (在线测试) (源码)
- shape-outside-linear-gradient-009.html (在线测试) (源码)
- shape-outside-linear-gradient-010.html (在线测试) (源码)
- shape-outside-linear-gradient-011.html (在线测试) (源码)
- shape-outside-linear-gradient-012.html (在线测试) (源码)
- shape-outside-linear-gradient-013.html (在线测试) (源码)
- shape-outside-linear-gradient-014.html (在线测试) (源码)
- shape-outside-linear-gradient-015.html (在线测试) (源码)
- shape-outside-linear-gradient-016.html (在线测试) (源码)
- shape-outside-radial-gradient-001.html (在线测试) (源码)
- shape-outside-radial-gradient-002.html (在线测试) (源码)
- shape-outside-radial-gradient-003.html (在线测试) (源码)
- shape-outside-radial-gradient-004.html (在线测试) (源码)
- shape-image-000.html (在线测试) (源码)
- shape-image-001.html (在线测试) (源码)
- shape-image-002.html (在线测试) (源码)
- shape-image-003.html (在线测试) (源码)
- shape-image-004.html (在线测试) (源码)
- shape-image-005.html (在线测试) (源码)
- shape-image-006.html (在线测试) (源码)
- shape-image-007.html (在线测试) (源码)
- shape-image-008.html (在线测试) (源码)
- shape-image-009.html (在线测试) (源码)
- shape-image-010.html (在线测试) (源码)
- shape-image-011.html (在线测试) (源码)
- shape-image-012.html (在线测试) (源码)
- shape-image-013.html (在线测试) (源码)
- shape-image-014.html (在线测试) (源码)
- shape-image-015.html (在线测试) (源码)
- shape-image-016.html (在线测试) (源码)
- shape-image-017.html (在线测试) (源码)
- shape-image-018.html (在线测试) (源码)
- shape-image-019.html (在线测试) (源码)
- shape-image-020.html (在线测试) (源码)
- shape-image-021.html (在线测试) (源码)
- shape-image-022.html (在线测试) (源码)
- shape-image-023.html (在线测试) (源码)
- shape-image-024.html (在线测试) (源码)
- shape-image-025.html (在线测试) (源码)
- shape-image-026.html (在线测试) (源码)
- shape-image-027.html (在线测试) (源码)
- shape-image-028.html (在线测试) (源码)
- shape-image-029.html (在线测试) (源码)
- shape-outside-circle-013.html (在线测试) (源码)
- shape-outside-circle-014.html (在线测试) (源码)
- shape-outside-circle-015.html (在线测试) (源码)
- shape-outside-circle-016.html (在线测试) (源码)
- shape-outside-circle-017.html (在线测试) (源码)
- shape-outside-circle-018.html (在线测试) (源码)
- shape-outside-circle-019.html (在线测试) (源码)
- shape-outside-circle-020.html (在线测试) (源码)
- shape-outside-circle-021.html (在线测试) (源码)
- shape-outside-circle-022.html (在线测试) (源码)
- shape-outside-circle-024.html (在线测试) (源代码)
- shape-outside-circle-025.html (在线测试) (源代码)
- shape-outside-circle-026.html (在线测试) (源代码)
- shape-outside-circle-027.html (在线测试) (源代码)
- shape-outside-circle-028.html (在线测试) (源代码)
- shape-outside-circle-029.html (在线测试) (源代码)
- shape-outside-circle-030.html (在线测试) (源代码)
- shape-outside-circle-031.html (在线测试) (源代码)
- shape-outside-circle-032.html (在线测试) (源代码)
- shape-outside-circle-033.html (在线测试) (源代码)
- shape-outside-circle-034.html (在线测试) (源代码)
- shape-outside-circle-035.html (在线测试) (源代码)
- shape-outside-circle-036.html (在线测试) (源代码)
- shape-outside-circle-037.html (在线测试) (源代码)
- shape-outside-circle-038.html (在线测试) (源代码)
- shape-outside-circle-041.html (在线测试) (源代码)
- shape-outside-circle-042.html (在线测试) (源代码)
- shape-outside-circle-043.html (在线测试) (源代码)
- shape-outside-circle-044.html (在线测试) (源代码)
- shape-outside-circle-047.html (在线测试) (源代码)
- shape-outside-circle-048.html (在线测试) (源代码)
- shape-outside-circle-049.html (在线测试) (源代码)
- shape-outside-circle-050.html (在线测试) (源代码)
- shape-outside-circle-051.html (在线测试) (源代码)
- shape-outside-circle-052.html (在线测试) (源代码)
- shape-outside-circle-053.html (在线测试) (源代码)
- shape-outside-circle-054.html (在线测试) (源代码)
- shape-outside-circle-055.html (在线测试) (源代码)
- shape-outside-circle-056.html (在线测试) (源代码)
- shape-outside-circle-integer-overflow-crash.html (在线测试) (源代码)
- shape-outside-ellipse-013.html (在线测试) (源代码)
- shape-outside-ellipse-014.html (在线测试) (源代码)
- shape-outside-ellipse-015.html (在线测试) (源代码)
- shape-outside-ellipse-016.html (在线测试) (源代码)
- shape-outside-ellipse-017.html (在线测试) (源代码)
- shape-outside-ellipse-018.html (在线测试) (源代码)
- shape-outside-ellipse-019.html (在线测试) (源代码)
- shape-outside-ellipse-020.html (在线测试) (源代码)
- shape-outside-ellipse-021.html (在线测试) (源代码)
- shape-outside-ellipse-022.html (在线测试) (源代码)
- shape-outside-ellipse-023.html (在线测试) (源代码)
- shape-outside-ellipse-024.html (在线测试) (源代码)
- shape-outside-ellipse-025.html (在线测试) (源代码)
- shape-outside-ellipse-030.html (在线测试) (源代码)
- shape-outside-ellipse-031.html (在线测试) (源代码)
- shape-outside-ellipse-032.html (在线测试) (源代码)
- shape-outside-ellipse-033.html (在线测试) (源代码)
- shape-outside-ellipse-034.html (在线测试) (源代码)
- shape-outside-ellipse-035.html (在线测试) (源代码)
- shape-outside-ellipse-036.html (在线测试) (源代码)
- shape-outside-ellipse-037.html (在线测试) (源代码)
- shape-outside-ellipse-038.html (在线测试) (源代码)
- shape-outside-ellipse-039.html (在线测试) (源代码)
- shape-outside-ellipse-040.html (在线测试) (源代码)
- shape-outside-ellipse-041.html (在线测试) (源代码)
- shape-outside-ellipse-042.html (在线测试) (源代码)
- shape-outside-ellipse-043.html (在线测试) (源代码)
- shape-outside-ellipse-044.html (在线测试) (源代码)
- shape-outside-ellipse-045.html (在线测试) (源代码)
- shape-outside-ellipse-046.html (在线测试) (源代码)
- shape-outside-ellipse-047.html (在线测试) (源代码)
- shape-outside-ellipse-048.html (在线测试) (源代码)
- shape-outside-ellipse-049.html (在线测试) (源代码)
- shape-outside-ellipse-050.html (在线测试) (源代码)
- shape-outside-ellipse-051.html (在线测试) (源代码)
- shape-outside-ellipse-052.html (在线测试) (源代码)
- shape-outside-ellipse-integer-overflow-crash.html (在线测试) (源代码)
- shape-outside-inset-010.html (在线测试) (源代码)
- shape-outside-inset-011.html (在线测试) (源代码)
- shape-outside-inset-012.html (在线测试) (源代码)
- shape-outside-inset-013.html (在线测试) (源代码)
- shape-outside-inset-014.html (在线测试) (源代码)
- shape-outside-inset-015.html (在线测试) (源代码)
- shape-outside-inset-016.html (在线测试) (源代码)
- shape-outside-inset-017.html (在线测试) (源代码)
- shape-outside-inset-020.html (在线测试) (源代码)
- shape-outside-inset-021.html (在线测试) (源代码)
- shape-outside-inset-022.html (在线测试) (源代码)
- shape-outside-inset-023.html (在线测试) (源代码)
- shape-outside-inset-024.html (在线测试) (源代码)
- shape-outside-inset-025.html (在线测试) (源代码)
- shape-outside-inset-026.html (在线测试) (源代码)
- shape-outside-inset-027.html (在线测试) (源代码)
- shape-outside-inset-028.html (在线测试) (源代码)
- shape-outside-inset-029.html (在线测试) (源代码)
- shape-outside-inset-030.html (在线测试) (源代码)
- shape-outside-inset-031.html (在线测试) (源代码)
- shape-outside-inset-refcrash.html (在线测试) (源代码)
- shape-outside-polygon-007.html (在线测试) (源代码)
- shape-outside-polygon-008.html (在线测试) (源代码)
- shape-outside-polygon-009.html (在线测试) (源代码)
- shape-outside-polygon-010.html (在线测试) (源代码)
- shape-outside-polygon-011.html (在线测试) (源代码)
- shape-outside-polygon-012.html (在线测试) (源代码)
- shape-outside-polygon-013.html (在线测试) (源代码)
- shape-outside-polygon-014.html (在线测试) (源代码)
- shape-outside-polygon-015.html (在线测试) (源代码)
- shape-outside-polygon-016.html (在线测试) (源代码)
- shape-outside-polygon-017.html (在线测试) (源代码)
- shape-outside-polygon-018.html (在线测试) (源代码)
- shape-outside-polygon-019.html (在线测试) (源代码)
- shape-outside-polygon-020.html (在线测试) (源代码)
- shape-outside-polygon-021.html (在线测试) (源代码)
- shape-outside-polygon-022.html (在线测试) (源代码)
- shape-outside-polygon-023.html (在线测试) (源代码)
- shape-outside-polygon-024.html (在线测试) (源代码)
- shape-outside-polygon-025.html (在线测试) (源代码)
- shape-outside-polygon-032.html (在线测试) (源代码)
- shape-outside-polygon-crash.html (在线测试) (源代码)
- shape-image-threshold-000.html (在线测试) (源代码)
- shape-image-threshold-001.html (在线测试) (源代码)
- shape-image-threshold-002.html (在线测试) (源代码)
- shape-image-threshold-003.html (在线测试) (源代码)
- shape-margin-000.html (在线测试) (源代码)
- shape-margin-001.html (在线测试) (源代码)
- shape-margin-002.html (在线测试) (源代码)
- shape-margin-003.html (在线测试) (源代码)
- shape-margin-004.html (在线测试) (源代码)
- shape-margin-005.html (在线测试) (源代码)
- shape-outside-box-000.html (在线测试) (源码)
- shape-outside-circle-000.html (在线测试) (源代码)
- shape-outside-circle-001.html (在线测试) (源代码)
- shape-outside-circle-002.html (在线测试) (源代码)
- shape-outside-circle-003.html (在线测试) (源代码)
- shape-outside-circle-004.html (在线测试) (源代码)
- shape-outside-circle-005.html (在线测试) (源代码)
- shape-outside-circle-006.html (在线测试) (源代码)
- shape-outside-circle-007.html (在线测试) (源代码)
- shape-outside-circle-008.html (在线测试) (源代码)
- shape-outside-circle-009.html (在线测试) (源代码)
- shape-outside-circle-010.html (在线测试) (源代码)
- shape-outside-circle-011.html (在线测试) (源代码)
- shape-outside-computed-shape-000.html (在线测试) (源代码)
- shape-outside-computed-shape-001.html (在线测试) (源代码)
- shape-outside-ellipse-000.html (在线测试) (源代码)
- shape-outside-ellipse-001.html (在线测试) (源代码)
- shape-outside-ellipse-002.html (在线测试) (源代码)
- shape-outside-ellipse-003.html (在线测试) (源代码)
- shape-outside-ellipse-004.html (在线测试) (源代码)
- shape-outside-ellipse-005.html (在线测试) (源代码)
- shape-outside-ellipse-006.html (在线测试) (源代码)
- shape-outside-ellipse-007.html (在线测试) (源代码)
- shape-outside-ellipse-008.html (在线测试) (源代码)
- shape-outside-ellipse-009.html (在线测试) (源代码)
- shape-outside-ellipse-010.html (在线测试) (源代码)
- shape-outside-ellipse-011.html (在线测试) (源代码)
- shape-outside-inset-000.html (在线测试) (源代码)
- shape-outside-inset-001.html (在线测试) (源代码)
- shape-outside-inset-0010.html (在线测试) (源代码)
- shape-outside-inset-002.html (在线测试) (源代码)
- shape-outside-inset-003.html (在线测试) (源代码)
- shape-outside-inset-004.html (在线测试) (源代码)
- shape-outside-inset-005.html (在线测试) (源代码)
- shape-outside-inset-006.html (在线测试) (源代码)
- shape-outside-inset-007.html (在线测试) (源代码)
- shape-outside-inset-008.html (在线测试) (源代码)
- shape-outside-inset-009.html (在线测试) (源代码)
- shape-outside-polygon-000.html (在线测试) (源代码)
- shape-outside-polygon-001.html (在线测试) (源代码)
- shape-outside-polygon-002.html (在线测试) (源代码)
- shape-outside-polygon-003.html (在线测试) (源代码)
- shape-outside-polygon-004.html (在线测试) (源代码)
- shape-outside-polygon-005.html (在线测试) (源代码)
- shape-outside-polygon-006.html (在线测试) (源代码)
- shape-outside-shape-arguments-000.html (在线测试) (源代码)
- shape-outside-shape-arguments-001.html (在线测试) (源代码)
- shape-outside-shape-box-pair-000.html (在线测试) (源码)
- shape-outside-shape-inherit-000.html (在线测试) (源代码)
- shape-outside-shape-initial-000.html (在线测试) (源代码)
- shape-outside-shape-none-000.html (在线测试) (源代码)
- shape-outside-shape-notation-000.html (在线测试) (源代码)
- shape-outside-001.html (在线测试) (源代码)
- shape-outside-002.html (在线测试) (源代码)
- shape-outside-003.html (在线测试) (源代码)
- shape-outside-004.html (在线测试) (源代码)
- shape-outside-005.html (在线测试) (源代码)
- shape-outside-006.html (在线测试) (源代码)
- shape-outside-007.html (在线测试) (源代码)
- shape-outside-008.html (在线测试) (源代码)
- shape-outside-010.html (在线测试) (源代码)
- shape-outside-011.html (在线测试) (源代码)
- shape-outside-012.html (在线测试) (源代码)
- shape-outside-013.html (在线测试) (源代码)
- shape-outside-014.html (在线测试) (源代码)
- shape-outside-015.html (在线测试) (源代码)
- shape-outside-016.html (在线测试) (源代码)
- shape-outside-017.html (在线测试) (源代码)
- shape-outside-018.html (在线测试) (源代码)
- shape-outside-019.html (在线测试) (源代码)
6.2. 选择图像像素:shape-image-threshold 属性
shape-image-threshold 属性定义了用于通过图像提取形状的 Alpha 通道阈值。值为 0.5 意味着形状将包含所有不透明度大于 50% 的像素。
| 名称 | shape-image-threshold |
|---|---|
| 值 | <opacity-value> |
| 初始值 | 0 |
| 应用于 | 浮点数 |
| 可继承 | 否 |
| 百分比 | 不可用 |
| 计算值 | 指定的数字,限制在 [0,1] 范围内 |
| 规范顺序 | 按语法 |
| 动画类型 | 按计算值 |
该属性的取值含义如下
- <number>(数字)
- 设置用于从图像中提取形状的阈值。形状由 Alpha 值大于该阈值的像素定义。如果阈值超出 0.0(完全透明)到 1.0(完全不透明)的范围,将被截断至该范围。
注意: 未来版本的 CSS Shapes 可能会定义一个开关,用于使用图像的亮度数据而非 Alpha 数据。届时,shape-image-threshold 将被扩展,根据开关状态将其阈值应用于 Alpha 或亮度。
测试
- shape-image-threshold-interpolation.html (在线测试) (源代码)
- inheritance.html (在线测试) (源码)
- shape-image-threshold-computed.html (在线测试) (源代码)
- shape-image-threshold-invalid.html (在线测试) (源码)
- shape-image-threshold-valid.html (在线测试) (源码)
- shape-image-threshold-000.html (在线测试) (源代码)
- shape-image-threshold-001.html (在线测试) (源代码)
- shape-image-threshold-002.html (在线测试) (源代码)
- shape-image-threshold-003.html (在线测试) (源代码)
6.3. 扩展形状:shape-margin 属性
shape-margin 属性为 shape-outside 添加外边距。这定义了一个新的形状,它是包含所有距离基础形状上某一点法线方向 shape-margin 距离的点的最小轮廓(收缩包裹意义上的)。这包括基础形状中的任何边缘或线条部分。注意,在无法定义法线的点(例如尖点或线端),则取以该点为中心、半径为 shape-margin 的圆上的所有点。
通过应用 shape-outside 产生的新形状决定了 浮动区域,并且必须在做出任何 换行 决策之前构建完成。
此属性仅接受非负值。
| 名称 | shape-margin |
|---|---|
| 值 | <length-percentage [0,∞]> |
| 初始值 | 0 |
| 应用于 | 浮动元素和 首字下沉框 |
| 可继承 | 否 |
| 百分比 | 参考包含块的 行内尺寸 |
| 计算值 | 计算出的 <length-percentage> 值 |
| 规范顺序 | 按语法 |
| 动画类型 | 按计算值 |
- <length-percentage [0,∞]>
- 将形状的外边距设置为指定值。
注意: 添加 shape-margin 不允许浮动区域延伸到浮动元素的 margin-box 之外。可能需要同时应用额外的 margin 以避免裁剪。
由 shape-margin 从多边形 shape-outside 创建的偏移。较浅的蓝色区域显示了 100x100px 浮动中的形状,深蓝色区域显示了 10px 的偏移。
.float {
width: 100px;
height: 100px;
shape-outside: polygon(10px 10px, 90px 50px, 40px 50px, 90px 90px, 10px 90px);
shape-margin: 10px;
}

如果将 shape-margin 添加到示例 6 中的 CSS 标志,则围绕形状 换行 的行框会进一步缩短。如果图像的 Alpha 通道延伸到图像的右边缘,则应应用一些额外的 margin-right,以确保形状不会被 margin-box 裁剪。
#CSSlogo {
shape-margin: 35px;
margin-right: 35px;
}
测试
- shape-margin-composition.html (在线测试) (源代码)
- shape-margin-interpolation.html (在线测试) (源代码)
- inheritance.html (在线测试) (源码)
- shape-margin-computed.html (在线测试) (源代码)
- shape-margin-invalid.html (在线测试) (源代码)
- shape-margin-valid.html (在线测试) (源代码)
- shape-outside-margin-box-001.html (在线测试) (源码)
- shape-outside-margin-box-002.html (在线测试) (源码)
- shape-outside-margin-box-border-radius-001.html (在线测试) (源码)
- shape-outside-margin-box-border-radius-002.html (在线测试) (源码)
- shape-outside-margin-box-border-radius-003.html (在线测试) (源码)
- shape-outside-margin-box-border-radius-004.html (在线测试) (源码)
- shape-outside-margin-box-border-radius-005.html (在线测试) (源码)
- shape-outside-margin-box-border-radius-006.html (在线测试) (源码)
- shape-outside-margin-box-border-radius-007.html (在线测试) (源码)
- shape-outside-margin-box-border-radius-008.html (在线测试) (源码)
- shape-margin-000.html (在线测试) (源代码)
- shape-margin-001.html (在线测试) (源代码)
- shape-margin-002.html (在线测试) (源代码)
- shape-margin-003.html (在线测试) (源代码)
- shape-margin-004.html (在线测试) (源代码)
- shape-margin-005.html (在线测试) (源代码)
7. 隐私考量
目前尚未针对此规范提出隐私问题。
8. 安全考量
由于 shape-outside 的 <image> 值可能会以新方式暴露某些图像数据,因此其使用仅限于经 CORS 批准的图像。
致谢
本规范得益于以下人士的贡献:Tab Atkins Jr., Amelia Bellamy-Royds, Oriol Brufau, Andrei Bucur, Alexandru Chiculita, Boris Chiou, Emilio Cobos Álvarez, Elika Etemad, Arron Eicholz, Sylvain Galineau, Daniel Glazman, Arno Gourdol, Zoltan Horvath, Chris Jones, Bem Jones-Bey, Ian Kilpatrick, Guillaume Lebas, Ting-Yu Lin, Eric Meyer, Marcus Mielke, Alex Mogilevsky, Hans Muller, Mihnea Ovidenie, Virgil Palanciuc, Noam Rosenthal, Robert Sanderson, Dirk Schulze, Jen Simmons, Peter Sorotokin, Bear Travis, Lea Verou, Eugene Veselov, Brad Werth, Stephen Zilles 以及 CSS 工作组成员。
变更日志
自 2022年11月15日
- 增加了 Web 平台测试注解
- 更改了 SVG 形状中 path() 的默认 fill-rule
- 阐明了 shape-margin 和浮动区域的交互
- 增加了多边形圆角示例
- 将所有基本形状包含在 issue #9728 的属性正文中
- 增加了多边形顶点圆角的起始内容
- 使用 opacity-value(值)而非 opacity(属性)作为 issue #8311 中 shape-image-threshold 的值
- 将 <alpha-value> 替换为 <opacity>
- 阐明了 shape-outside 适用于 issue #5160 的首字下沉框
- 基于 Images 中的 <radial-size> 重写了 ellipse()/circle() 定义,针对 issue #824
- 明确位置默认值可被其他规范(如 Motion)覆盖。
- 针对 issue #8695 修复了形状序列化部分,修正了示例
- 为 issue #9053 修复了 xywh() 的计算值
- 使用隐式可选逗号重写了语法 PR #9650
- 清理了 <*-box> 定义 PR #9505
- 在属性定义中增加了范围表示法
- 为 issue #9843 增加了 polygon() 的顶点圆角
- 更新了 shape-outside 正文以包含所有 <basic-shape>,针对 issue #9728
- 阐明了 shape-margin 对浮动区域的贡献,针对 issue #2949
- 增加了针对 SVG 形状的 fill-rule 默认处理,来自 issue #3468
- 将 'shape()' 从 level 2 移入
自 2014年3月20日
- 阐明了 shape-margin 的计算值
- 阐明了默认位置值的序列化,针对 issue #402
- 阐明了空圆和椭圆,针对 issue #850
- 取消了属性定义表中的“媒体:”条目,与其他 CSS 模块保持一致
- 更新了从 CSS 2 到 CSS Box Model 3 的盒模型引用
- 更新了属性定义表中的计算值和动画类型
- 阐明了 shape-outside 属性的计算值,针对 issue #4042
- 阐明了 shape-image-threshold 可以接受百分比值(像任何 Alpha 值一样),针对 issue #4102
- 将 path() 从 level 2 移回
- 增加了 margin-box 的负边距处理,针对 issue #675
- 移除了位置值的特殊情况序列化,针对 issue #2301
- 增加了对 shape-margin 示例的说明
- 增加了 margin-box 形状的 margin=0 情况,针对 issue #675
- 更改了关于退化形状的规则,改为使用形状边缘,针对 issue #2375
- 阐明了无效的路径字符串会使 path() 无效,针对 issue #392
- 重写了嵌入矩形的定义,增加了 auto 值,增加了示例
- 阐明了基本形状矩形函数的计算值
- 各类标记修复,包括使用范围表示法和导出定义的术语以供其他规范使用
- 将隐私和安全考量拆分为单独的章节
自 2014年2月11日
- 在第一个示例中将 div 替换为图像
- 在最后一个序列化示例中添加 0px
自 2013年12月3日
- 更新了基本形状的计算值和序列化
- 增加了 margin-box 示例
- 将 shape-outside 的 auto 更改为 none
- 定义了 shape-box 而非重定义 box
- 阐明了图像形状可能会产生多条路径
自 2013年6月20日
- 增加了从盒子值部分提取形状
- 更新了基本形状插值
- 允许负嵌入,不允许负半径
- 将相关更改为参考
- 移除 box-sizing 依赖,添加相关的盒关键词
- 将 circle() 和 ellipse() 更改为使用径向渐变语法
- 将 rectangle() 推迟到 level 2
- 阐明了图像形状的尺寸和定位
- 将 inset-rectangle() 更改为 inset()
- 使 shape-image-threshold 未来可能应用于亮度
- 为 shape-outside URL 增加了 CORS 获取
- 将 shape-outside 值从 <uri> 更改为 <image>
- 移除 '基于自动调整大小的百分比解析为 0'
- 将 shape-image-threshold 的初始值更改为 0.0
- 将浮动定位更改为不受 shape-outside 影响
- 浮动上的形状被裁剪到浮动的 margin-box
自 2012年5月3日
- 将 SVG 元素的形状推迟到未来的 Shapes level
- 将 shape-inside 推迟到未来的 Shapes level
- 将排斥(exclusions)从形状中拆分为单独的模块
- 在基本形状中增加了 inset-rectangle()
- 更改了 shape-inside 溢出图以显示排斥行为
- 更改了 shape-inside 以贡献于换行上下文
- 相对于换行内容的书写模式定义了排斥边缘
- 使 start、end、before 和 after 的使用保持一致
- 增加了基本形状的插值
- 将基本形状更改为依赖于使用 box-sizing 指定的盒子
- 增加了 shape-inside 的溢出行为。
- 增加了 wrap-flow:minimum。
- 阐明了处理模型。
- 将 wrap-margin 和 wrap-padding 更改为 shape-margin 和 shape-padding。
- 移除了 wrap 速记属性。
自 2011年12月13日
- 阐明了处理模型。
- 阐明了与浮动元素的交互。
- 阐明了排斥元素建立一个新的块格式化上下文。