版权所有 © 2014 W3C®(MIT,ERCIM,庆应义塾大学,北京航空航天大学),保留所有权利。适用 W3C 责任、商标以及 文档使用 规则。
CSS 排除定义了任意的 **排除区域**,内联内容([CSS21])可以围绕该区域流动。CSS 排除可以在任意 CSS 块级元素上定义。CSS 排除扩展了先前仅限于浮动的内容环绕概念。
CSS 是一种用于描述结构化文档(如 HTML 与 XML)在屏幕、纸张、语音等介质上的渲染方式的语言。
本节说明了本文档在发布时的状态。其他文档可能已取代本文件。当前 W3C 发布物以及本技术报告的最新修订版列表可在 W3C 技术报告索引(https://w3org.cn/TR/) 中查阅。
本文档是 W3C 工作草案。
发布为工作草案并不意味着获得 W3C 成员的认可。这是一份草案文档,可能随时被其他文档更新、替换或废弃。将其作为进行中的工作以外的引用是不恰当的。
此(已归档)公共邮件列表 www-style@w3.org(参见 说明)是讨论本规范的首选渠道。发送电子邮件时,请在主题中加入 “css-exclusions”,最好采用如下格式:“[css-exclusions] …评论摘要…”。
本文件由遵循 2004年2月5日 W3C 专利政策 的小组制作。W3C 维护一份 公开的专利披露列表,列出与小组交付物相关的专利披露;该页面亦包含披露专利的方法说明。若个人实际了解某项专利并认为该专利包含 必要权利要求,必须按照 W3C 专利政策第 6 节进行披露。
本文档受 2014 年 8 月 1 日 W3C 过程文档 约束。
本节不具有规范性。
本规范定义了允许内联流内容环绕元素的 排除区域 的特性。
如果用户代理同时实现了 CSS 排除和 CSS Shapes,则 shape-outside 属性定义的排除区域将取代边框盒。
wrapping area(即从自身 内容区域 中减去 环绕上下文)内环绕其内联流内容。除非使用 wrap-through 属性显式重置,否则盒子会继承其 包含块 的 环绕上下文。
排除元素定义的 排除区域 会贡献给其包含块的 环绕上下文,从而影响该包含块的后代的布局。
元素在其 内容区域 内布局内联内容,并在其关联的 环绕上下文 中的 排除区域 周围换行。如果该元素本身是排除,则它 **不会** 环绕自己的排除区域;其它排除对该元素的影响受 z-index 属性控制,详见 “排除的顺序” 小节。
当元素的 wrap-flow 属性的计算值不是 auto 时,该元素就成为排除。
| 名称 | wrap-flow |
|---|---|
| 值 | auto | both | start | end | minimum | maximum | clear |
| 初始值 | auto |
| 应用于 | 块级元素。 |
| 可继承 | 否 |
| 百分比 | 不适用 |
| 媒体 | 视觉 |
| 计算值 | 如规格所述,除非元素的 float 计算值不是 none,否则会把计算值设为 auto。 |
| 可动画 | 否 |
该属性的取值含义如下
如果属性的计算值为 auto,该元素 **不** 成为 排除。
否则,当元素的计算后的 wrap-flow 属性值为 both、start、end、minimum、maximum 或 clear 时,该元素即为 排除元素。其 排除区域 会贡献给其包含块的 环绕上下文,从而导致包含块的后代在其 排除区域 周围换行。
使用 wrap-flow 为 start 的排除:在不同书写模式下的交互示例。
确定排除的相关边缘取决于围绕 排除区域 的内容的 书写模式([CSS3‑WRITING‑MODES])。
一个 排除元素 为其内容建立一个新的 块格式化上下文(参见 [CSS21])。
组合排除
上图说明了排除的组合方式。最外层的盒子代表元素的内容盒。深灰色的 A、B、C、D 盒子代表元素的 环绕上下文 中的排除。A、B、C、D 的 wrap-flow 计算值分别为 both、start、end 与 clear。浅灰色区域显示了因对应的 wrap-flow 值导致的额外排除区域。例如,在左‑右书写模式下,B 的右侧区域不能用于内联布局,因为 B 的 wrap-flow 为 start。
蓝色背景区域显示左‑右书写模式元素的内联内容可用布局区域。所有以浅色或深色灰色渲染的区域均不可用于(左‑右书写模式)内联内容布局。
<div id="grid">
<div id="top-right" class="exclusion"></div>
<div id="bottom-left" class="exclusion"></div>
<div id="content">Lorem ipsum…</div>
</div>
<style type="text/css">
#grid {
width: 30em;
height: 30em;
display: grid;
grid-columns: 25% 25% 25% 25%;
grid-rows: 25% 25% 25% 25%;
#top-right {
grid-column: 3;
grid-row: 2;
}
#bottom-left {
grid-column: 2;
grid-row: 3;
}
.exclusion {
wrap-flow: <see below>
}
#content {
grid-row: 1;
grid-row-span: 4;
grid-column: 1;
grid-column-span: 4;
}
</style>
下图展示了不同 wrap-flow 值的视觉渲染效果。灰色网格线标记网格单元,蓝色区域为排除盒子(由网格定位)。
.exclusion{ wrap-flow: auto; } |
.exclusion{ wrap-flow: both; } |
![]() |
![]() |
.exclusion{ wrap-flow: start; } |
.exclusion{ wrap-flow: end; } |
![]() |
![]() |
.exclusion{ wrap-flow: minimum; } |
.exclusion{ wrap-flow: maximum; } |
![]() |
![]() |
.exclusion{ wrap-flow: clear; } |
|
![]() |
一个 排除 会影响其 **包含块**(见 CSS 2.1 10.1)下的所有内联流内容,以及同一包含块内部所有后代元素的内联流内容。要阻止来自元素外部的排除影响,可使用 wrap-through 属性(见下文 排除的传播 小节)。
提醒一下:对 position:fixed 的排除,其 **包含块** 由根元素建立。
默认情况下,元素会继承其父元素的 环绕上下文——也就是说,它会受到 **在元素外部** 定义的排除影响。
将 wrap-through 属性设为 none 可阻止元素继承其父节点的 环绕上下文。换言之,**在元素外部** 定义的排除对该元素的子代布局 **不再起作用**。
由元素后代定义的排除仍会贡献给其包含块的 环绕上下文。如果该包含块是一个 wrap-through 为 none 的元素的子代,或者该元素自身,则排除仍会影响该包含块子代的布局。
| 名称 | wrap-through |
|---|---|
| 值 | wrap | none |
| 初始值 | wrap |
| 应用于 | 块级元素 |
| 可继承 | 否 |
| 百分比 | 不适用 |
| 媒体 | 视觉 |
| 计算值 | 按指定值 |
| 可动画 | 否 |
该属性的取值含义如下
<style type="text/css">
#grid {
display: grid;
grid-columns: 25% 50% 25%;
grid-rows: 25% 25% 25% 25%;
}
#exclusion {
grid-row: 2;
grid-row-span: 2;
grid-column: 2;
wrap-flow: <see below>
}
#rowA, #rowB {
grid-row-span: 2;
grid-column: 1;
grid-column-span: 3;
}
#rowA {
grid-row: 1;
}
#rowB {
grid-row: 3;
}
</style>
<style type="text/css">
.exclusion {
wrap-flow: both;
position: absolute;
left: 20%;
top: 20%;
width: 50%;
height: 50%;
background-color: rgba(220, 230, 242, 0.5);
}
</style>
<div id="grid">
<div class=”exclusion”></div>
<div id="rowA" style=”wrap-through: wrap;”> Lorem ipsum dolor sit amet...</div>
<div id="rowB" style=”wrap-through: none;”> Lorem ipsum dolor sit amet...</div>
</div>

排除遵循绘制顺序(见 [CSS21] 附录 E)。它们的应用顺序与文档中声明的顺序相反——最后声明的排除位于最上层,因而会影响所有之前声明的排除或同一包含块的后代元素的内联流内容。可使用 z-index 来改变 定位 排除盒子的层级(参见 [CSS21])。**静态定位** 的排除不受 z-index 影响,仍然遵循绘制顺序。
排除的层级示例。
<style type="text/css">
.exclusion {
wrap-flow: both;
position: absolute;
width: 200px;
}
.topleft {
top: 10px;
left: 10px;
background-color: lightblue;
}
.middle {
top: 90px;
left: 90px;
background-color: lightgreen;
}
.bottomright {
top: 170px;
left: 170px;
background-color: pink;
}
</style>
<div class="exclusion topleft">
The top left div...
</div>
<div class="exclusion middle">
The middle div...
</div>
<div class="exclusion bottomright">
The bottom right div...
</div>
.middle { z-index: auto; } |
.middle { z-index: 1; } |
![]() |
![]() |
CSS 排除的处理模型是否有误?
当前草案提供了一个排除模型,但缺少碰撞规避机制。现有的 CSS 排除模型(即浮动)同时具备排除与碰撞规避行为。有人担心在没有碰撞规避的情况下使用排除,特别是在 **绝对定位** 元素时,可能会产生问题。应考虑以下三种方案:
应用排除是一个两步过程
在此步骤中,用户代理确定每个 包含块 属于哪一个 排除区域。该步骤相对简单,只需依据 **包含块** 的定义以及 wrap-flow 的计算值(非 auto)的元素即可。
此步骤从 渲染树(参见 [CSS21])的顶部开始,代理会对每个包含块进行两子步骤的处理。
解析 排除盒子 在其 环绕上下文 中的定位与尺寸时,可能需要也可能不需要布局。例如,若排除盒子是 **绝对定位且已确定尺寸**,则无需布局即可得到其定位与尺寸。其他情况下,则需要布局其包含块的内容。
当需要布局时,布局会在 **不** 应用任何 排除区域 的前提下进行——即在没有 环绕上下文**的情况下**布局包含块。
步骤 2‑A 为所有 排除盒子 产生定位与尺寸。代理按从 **最上层** 开始的顺序逐个处理每个排除盒子,并为每个计算出的 排除区域 贡献给其 包含块 的 环绕上下文。
在解析 position:fixed 的 排除盒子 时,**滚动** 被忽略。
一旦计算出 包含块 的 环绕上下文,该上下文中的所有 排除盒子**均**从正常流中移除。
最后,布局包含块的内容,使内联内容围绕 环绕上下文 中的 排除区域。
如果包含块本身是 排除盒子,则 排除顺序 的规则决定哪些排除会影响该盒子的内联与后代内容。
本节通过一个示例说明排除的处理模型。示例意在保持简洁,同时仍能展示布局依赖与重新布局的核心问题。
以下代码片段包含两个排除,它们共同影响文档的内联内容。
<html>
<style>
#d1 {
position:relative;
height: auto;
color: #46A4E9;
border: 1px solid gray;
}
#e1 {
wrap-flow: both;
position: absolute;
left: 50%;
top: 50%;
width: 40%;
height: 40%;
border: 1px solid red;
margin-left: -20%;
margin-top: -20%;
}
#d2 {
position: static;
width: 100%;
height: auto;
color: #808080;
}
#e2 {
wrap-flow: both;
position: absolute;
right: 5ex;
top: 1em;
width: 12ex;
height: 10em;
border: 1px solid lime;
}
</style>
<body>
<div id="d1">
Lorem ipsusm ...
<p id="e1"></p>
</div>
<div id="d2">
Lorem ipsusm ...
<p id="e2" ></p>
</div>
</body>
</html>
下面的图示展示了:
DOM 树
生成的块盒的布局树
图示说明了在布局树中,元素对应的盒子有时会拥有不同于 DOM 树的层级结构。例如,e1 生成的盒子位于其包含块的盒子 d1-box 中,因为 e1 为 **绝对定位** 并且 d1 为 **相对定位**。而 e2 同样为绝对定位,但其包含块是 **初始包含块(ICB)**。详情参见 CSS 2.1 章节 10.1([CSS21])。
基于对所有元素的 **包含块** 计算,可确定它们各自所属的 环绕上下文。
e2 盒子:WC‑1(环绕上下文 1)d1 元素继承 body 的环绕上下文并将 e1-box 加入其中。因此其环绕上下文由 e1-box 与 e2-box 组成:WC‑2d2 元素继承 body 的环绕上下文:WC‑1在此步骤中,依次处理每个包含块。对每个包含块,概念上会经历两个阶段:
在本例中,这一过程分解为:
d1 元素的 环绕上下文**:RWC‑2**。d1 元素d2 元素的 环绕上下文**:RWC‑1**。d2 元素布局树中位于最顶层的环绕上下文包含 e2 排除。需要解析它的定位与尺寸。一般来说,解析排除的定位与尺寸**可能**或**可能不**需要布局其他内容。在本例中,由于 e2 为 **绝对定位** 并且其尺寸可在无需布局的情况下确定,所以无需额外布局即可得到其定位与尺寸。此时,RWC‑1 已完成解析,可用于后续的内联内容布局。
过程类似:需要解析 e1 排除的定位。此时,解析排除的定位与尺寸**需要**处理其包含块(这里是 d1),因为 e1 的尺寸与百分比长度依赖于 d1 盒子的尺寸。于是,先对 d1 进行一次 **不考虑任何环绕上下文**(即不应用排除)的布局,以获取 d1 盒子的尺寸。该布局产生了 e1 盒子的定位与尺寸。
此时,RWC‑2 已完成解析,因为 e1 与 e2 的定位与尺寸均已确定。
上述处理示例的关键在于:一旦元素的 环绕上下文**已**解析(即其排除的定位与尺寸已确定),即使随后因为元素尺寸变化而重新布局,该排除的定位与尺寸也**不会**再次被重新处理。这打破了环绕上下文解析与包含块布局之间可能出现的循环依赖。
浮动与排除在 **内联内容环绕** 方面具有相似性——内联内容会围绕浮动以及 排除区域 换行。但两者之间也存在显著差异。
浮动会影响排除的定位以及其行内内容的布局。例如,如果一个排除是恰好位于与浮动同一行的行内盒,则其位置(在 步骤 2-A 中计算得到的)会受到该浮动的影响,其他所有行内内容亦如此。
排除会影响浮动的定位,因为它们会影响行内内容。因此,在 步骤 2-B 中,浮动会避开 排除区域。
本规范的制定得益于 Andrei Bucur、Alexandru Chiculita、Arron Eicholz、Daniel Glazman、Arno Gourdol、Chris Jones、Bem Jones‑Bey、Marcus Mielke、Alex Mogilevsky、Hans Muller、Mihnea Ovidenie、Virgil Palanciuc、Florian Rivoal、Peter Sorotokin、Bear Travis、Eugene Veselov、Stephen Zilles 以及 CSS 工作组成员的贡献。
Conformance requirements are expressed with a combination of descriptive assertions and RFC 2119 terminology. The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in the normative parts of this document are to be interpreted as described in RFC 2119. However, for readability, these words do not appear in all uppercase letters in this specification.
本规范的全部文本均为规范性内容,除非明确标记为非规范性、示例或注释。[RFC2119]
本规范中的示例会以 “for example” 开头,或使用 class="example" 与规范性文本区分,如下所示:
这是一个说明性示例。
信息性注释以 “Note” 开头,并使用 class="note" 与规范性文本区分,如下所示:
注意,这是一个说明性注释。
建议(Advisements)是规范性章节,旨在引起特别注意,并使用 <strong class="advisement"> 与其他规范性文本区分开来,如下所示: 用户代理必须提供可访问的替代方案。
本规范为三类一致性定义了一致性要求。
如果样式表包含的所有使用本模块定义语法的语句,根据通用 CSS 语法及本模块定义的各功能语法均有效,则该样式表符合本规范。
如果渲染器除了按相应规范解释样式表外,还通过正确解析本规范定义的所有功能并相应地渲染文档来支持这些功能,则该渲染器符合本规范。然而,由于设备限制导致 UA 无法正确渲染文档,并不意味着该 UA 不符合规范。(例如,UA 无需在单色显示器上渲染颜色。)
如果创作工具编写的样式表根据通用 CSS 语法及本模块中各功能的语法是句法正确的,并符合本模块中描述的所有其他样式表一致性要求,则该创作工具符合本规范。
为了使作者能够利用前向兼容的解析规则来指定后备值,CSS 渲染器 **必须** 将其无法使用支持级别的任何 @规则、属性、属性值、关键字和其他语法结构视为无效(并 适当忽略)。特别地,用户代理 **不得** 在单一多值属性声明中选择性地忽略不支持的组件值而保留支持的值:如果任何值被视为无效(因为不支持的值必须如此),CSS 要求忽略整个声明。
为避免与未来 CSS 特性冲突,CSS 2.1 规范在 前缀语法 中保留了专用于专有和实验性扩展的语法。
在规范达到候选推荐(Candidate Recommendation)阶段之前,所有 CSS 特性的实现均视为实验性。CSS 工作组建议实现者对这些特性使用带供应商前缀的语法,包括在 W3C 工作草案中的特性。这样可以避免未来草案更改导致的不兼容。
一旦规范达到候选推荐阶段,非实验性实现即可成为可能,实现者应发布他们能够证明根据规范正确实现的任何 CR 级别特性的无前缀实现。
为建立并保持 CSS 在不同实现间的互操作性,CSS 工作组请求非实验性的 CSS 渲染器在发布任何 CSS 功能的无前缀实现之前,向 W3C 提交一份实现报告(并在必要时提交用于该实现报告的测试用例)。提交给 W3C 的测试用例需经 CSS 工作组审阅和修正。
有关提交测试用例与实现报告的更多信息,请访问 CSS 工作组网站的 https://w3org.cn/Style/CSS/Test/。如有疑问,请发送至 public-css-testsuite@w3.org 邮件列表。
| 名称 | 值 | 初始值 | 应用于 | 继承 | 百分比 | 媒体 | 可动画 | 计算值 |
|---|---|---|---|---|---|---|---|---|
| wrap-flow | auto | both | start | end | minimum | maximum | clear | auto | 块级元素。 | 否 | 不适用 | 视觉 | 否 | 如未另行指定,则取计算值;但如果元素的 float 计算值不是 none,则其计算值为 auto。 |
| wrap-through | wrap | none | wrap | 块级元素 | 否 | 不适用 | 视觉 | 否 | 按指定值 |
当前草案提供了一个排除模型,但缺少碰撞规避机制。现有的 CSS 排除模型(即浮动)同时具备排除与碰撞规避行为。有人担心在没有碰撞规避的情况下使用排除,特别是在 **绝对定位** 元素时,可能会产生问题。应考虑以下三种方案: