版权所有 © 2014 W3C®(MIT,ERCIM,庆应义塾大学,北京航空航天大学),保留所有权利。适用 W3C 责任、商标以及 文档使用 规则。
CSS Regions 模块允许一个或多个元素的内容流经一个或多个称为 CSS Regions 的框,按照 [CSS3-BREAK] 中定义的方式进行分段。该模块还定义了 CSSOM,以公开此分段的输入和输出。
CSS 是一种用于描述结构化文档(如 HTML 与 XML)在屏幕、纸张、语音等介质上的渲染方式的语言。本节说明了本文档在发布时的状态。其他文档可能已取代本文件。当前 W3C 发布物以及本技术报告的最新修订版列表可在 W3C 技术报告索引(https://w3org.cn/TR/) 中查阅。
发布为工作草案并不意味着获得 W3C 成员的认可。这是一份草案文档,可能随时被其他文档更新、替换或废弃。将其作为进行中的工作以外的引用是不恰当的。
(归档的)公共邮件列表 www-style@w3.org(参见 说明)是讨论本规范的首选渠道。发送邮件时,请在主题中加入 “css-regions”,最好写成:“[css-regions] …评论摘要…”。
本文件由遵循 2004年2月5日 W3C 专利政策 的小组制作。W3C 维护一份 公开的专利披露列表,列出与小组交付物相关的专利披露;该页面亦包含披露专利的方法说明。若个人实际了解某项专利并认为该专利包含 必要权利要求,必须按照 W3C 专利政策第 6 节进行披露。
本文档受 2014 年 8 月 1 日 W3C 过程文档 约束。
本节是非规范性的。
CSS Regions 背后的核心概念是能够声明“在*此处*(命名流)显示内容,并在*那里*(region chain)显示”。最简单的例子是
#this {
flow-into: my-flow;
}
#there {
flow-from: my-flow;
}
下面这两条声明会把匹配 #this 的元素放入名为 “my-flow” 的流中,并在匹配 #there 的元素盒子里显示 “my-flow” 的内容。此示例只有一个 named flow 的内容来源,以及一个 region chain 的盒子。命名流也可以有多个来源,并使用多个盒子来构成 region chain。
named flow 机制可以用于多种不同的场景——包括自定义溢出处理、内容聚合、链接显示盒子、杂志式布局,以及在分页视图中让内容流经特定区域。
<article> ...some content... </article>
<aside> ad or image content </aside>
在此情况下,
在此示例(为简化起见)我们使用额外的元素来创建这些盒子
<article> ...some content... </article>
<div class="top region"></div>
<aside> ad or image content </aside>
<div class="region"></div>
article {
flow-into: article-flow;
}
.region {
flow-from: article-flow;
}
.top {
max-height: 80vh;
}
因此,region chain 中的顶部盒子的高度被限制为视口高度的 80%。如果文章内容放不进该盒子,剩余部分会继续在
在上图中,灰色区域表示在初始视图中位于屏幕底部以下的内容。
此示例仅把两个盒子链接在一起,但可以向 region chain 中添加更多盒子,以在文章中定期交错其他内容。
自定义溢出处理可以通过链接一个单独的溢出盒子来实现。在本例中,溢出盒子嵌套在标记中的菜单里,仅在菜单展开时显示。
<nav> ...some links... </nav>
<div class="menu">
<nav></nav>
...some more links...
</div>
如果把主导航元素中的链接放入 named flow,该流即可同时流经主导航元素和菜单中的溢出导航盒子。
nav a {
flow-into: nav-link-flow;
}
nav {
flow-from: nav-link-flow;
}
随后可以对主导航元素和菜单设置约束,使得当屏幕过窄导致主导航元素无法完整显示所有链接时,溢出部分会自动移动到菜单中。
由于内容是通过 CSS 选择器分配到 named flow 的,内容可以来自多个来源。聚合后的结果可以显示在单个盒子中,或像上面那样流经多个盒子。
因此给定以下标记
<div class="breaking-news"></div>
<article>News story</article>
<article class="breaking">Sports story</article>
<article>News story</article>
<article class="breaking">Entertainment story</article>
<article>Sports story</article>
只需两行 CSS,即可把 “breaking” 文章显示在全部其他文章之上
.breaking {
flow-into: breaking-news;
}
.breaking-news {
flow-from: breaking-news;
}
如果 CSS 选择器能够访问到更多数据,就可以根据用户偏好将文章以其他方式重新排列(如把体育新闻放在顶部等)。
CSS Regions 与布局相互独立
任何 CSS 布局方式都可以用来创建、定位和设定可成为 CSS Regions 的盒子尺寸。
CSS Regions 模块不定义布局机制,旨在与现有以及未来的 CSS 布局设施协同工作。
CSS Regions 不必是元素
CSS Regions 模块独立于盒子的布局以及创建盒子的机制。
为简化起见,我们的示例倾向于使用元素来定义盒子。任何其他可用于在标记或样式中创建可样式化盒子的机制都可以代替,例如伪元素或 CSS 页面模板模块中提出的 @slot 规则 [CSS3-PAGE-TEMPLATE]。
使盒子成为 CSS Region 的唯一要求是该盒子必须使用 flow-from 属性。
A CSS Region 是一种块容器,且其关联有一个 named flow(参见 flow-from 属性)。
A region chain 是与某个 named flow 关联的一系列区域。CSS Regions 在区域链中按照它们的链序接收 named flow 的内容。CSS Regions 按文档顺序组织成 region chain。
A named flow 是与给定标识符关联的有序内容序列。named flow 中的内容按文档顺序排列。
使用 flow-into 属性可以将内容放入 named flow。named flow 中的内容会使用 flow-from 属性在关联的 region chain 中进行布局。
named flow 的内容会根据区域流断点规则在各区域之间进行分割。
当某些内容被移动到具有给定标识符的流中,或至少有一个 CSS Region 请求该流的内容时,就会创建一个 named flow。
在 named flow 上跨区域链进行分割类似于在页面之间(参见 [CSS3PAGE])或在多列元素的列盒之间(参见 [CSS3COL]named flow 内容的接收盒,其动态生成不在本规范范围之内。
每个 CSS Region 依次消耗其关联的 named flow 内容。只要没有出现自然或强制的区域断点,named flow 内容就会一直排布在当前区域中;一旦出现断点,链中的下一个区域就成为当前区域。如果在 region chain 中已经没有更多的 CSS Regions,但流中仍有剩余内容,则该链中最后一个 CSS Region 上的 region-fragment 属性将控制剩余内容的定位方式。
CSS Regions 模块遵循 CSS Fragmentation Module Level 3 中定义的分段规则(参见 [CSS3-BREAK])。
[Shadow]:getFlowByName 与 shadow DOM
‘flow-into’ 属性可以把元素或其内容放入一个 named flow。属于同一流的内容会在该流关联的区域链中进行布局。
| 名称 | flow-into |
|---|---|
| 值 | none | <ident> [element|content]? |
| 初始值 | none(无) |
| 应用于 | 所有元素,但不包括 伪元素(例如 ::first-line、::first-letter、::before 或 ::after)。 |
| 可继承 | 否 |
| 媒体 | 视觉 |
| 计算值 | 按指定值 |
flow-into 属性影响放入 named flow 的元素或内容的视觉格式化,以及负责排版 named flow 内容的区域链的布局。该属性不影响其指定元素的 CSS 级联与继承,也不影响 DOM [DOM] 中元素或内容的位置。它同样不影响非视觉媒体(例如 语音)中的排序,也不影响顺序导航模式(例如在链接之间循环,参见 nav-index [CSS3UI] 或 tabindex [HTML40])。
若要使 named flow 的内容进行视觉格式化,必须将其关联到一个区域链(一个或多个 CSS Regions)。如果没有为某个 named flow 建立区域链,则该流中的内容不会渲染:不会生成盒子,也不显示。
具有指定流的元素或内容的子元素如果也拥有指定流,则它们会成为该流中最新元素或内容的下一个兄弟节点。在某些情况下,子元素甚至可以成为其同一路流中祖先的下一个兄弟。
named flow 中的内容按文档顺序排序。视觉格式化模型使用命名流中内容之间的关系作为输入,而非它们在 DOM 中的位置。
在 region chain 中的每个 CSS region 为 named flow 中的绝对定位元素建立包含块(参见 [CSS21])。该链中的第一个 CSS region 同时也是该类绝对定位元素的初始包含块。Regions 并不会为 named flow 中的固定定位元素建立包含块,这类元素仍相对于视口或页面区域定位,即使它们已被重定向进入命名流。
第一个区域定义了整个流的主要 书写模式。后续区域的书写模式将被忽略。
flow-into 属性将元素移入流中,使用选择器时需要特别慎重。
例如:
table {flow-into: table-content}
将把所有位于 “table-content” named flow 中的表格移入。然而,
table > * {flow-into: table-content} ...
选择器将把所有表格元素的直接子元素移入 “table-content” named flow(若直接子元素是行,则通常会把多表格的行合并),但
table * {flow-into: table-content}
选择器会把所有表格元素的后代移入 “table-content” named flow,这会把元素树转换为按照开始标签顺序的扁平列表(这通常不是作者的本意)。这会导致表格元素的后代在 named flow 中成为兄弟,从而触发不同的处理(参见 CSS 2.1 的匿名表格对象)。此注记说明在为 flow-into 设置属性时,作者必须谨慎选择具体的选择器,以免产生意外结果。
将元素移入命名流的另一个后果是,周围的空白字符不会随之移动。如果你的代码是这样写的,
span {flow-into: span-content}
<span>one</span>
<span>two</span>
则 “span-content” 命名流的内容将变为
<span>one</span><span>two</span>
这会导致显示从 “one two” 变为 “onetwo”。如果空白字符是重要的,则需要把包含空白的父元素也移动到命名流中。
flow-from 属性把块容器变为区域,并与一个 named flow 关联。
| 名称 | flow-from |
|---|---|
| 值 | <ident> | none | inherit |
| 初始值 | none(无) |
| 应用于 | 非替换的 块容器。 未来的规范版本可能会扩展,以允许其他类型的容器接收流内容。 |
| 可继承 | 否 |
| 媒体 | 视觉 |
| 计算值 | 按指定值 |
如果 content 属性的计算值不是 normal(或伪元素的 none),则块容器不会成为 CSS Region。如果块容器或其祖先的 display 计算值为 none,同样不会成为 CSS Region。
除非被定向到具有关联 region chain 的 named flow,否则 CSS Region 的文档子节点不会进行视觉格式化。
当 flow-from 的计算值为 <ident> 且 content 的计算值为 none 时,会将块容器伪元素生成作为 CSS Regions,这对 [CSS21] 中的行为进行了更新。
当块容器的 flow-from 属性被设为有效的 <ident> 值时,即使该流中没有内容贡献,该块容器仍会成为 CSS Region。例如
<style>
.article{
flow-into: thread;
}
.region{
flow-from: thread;
}
</style>
<html>
<body>
<div class=region>div content</div>
</body>
</html>
没有元素匹配 .article 选择器,因此 thread 流中没有内容。然而,匹配 .region 选择器的块容器仍然关联到该空的 named flow,因此其子节点不会进行视觉格式化。
在撰写本注记时,总是导致非替换块容器的 display 值包括 block、inline-block、table-cell、table-caption 与 list-item。所有这些 display 值在有非替换元素的情况下都可作为区域使用。
flex 与 grid 的 display 值并不产生块容器(它们分别被定义为弹性容器和网格元素)。因此 flow-from 与这些 display 值组合时不会产生 CSS Region。
CSS Regions 会创建一个新的 层叠上下文。CSS Regions 建立一个新的 块格式化上下文。排除(参见 [CSS3-EXCLUSIONS])可能会影响区域链中内容的布局,正如非区域情况一样。
使用 region chains 时,一个元素可能会被拆分到多个盒子,这些盒子甚至可能重叠(例如绝对定位时)。因此同一元素的片段可能相互重叠。由于每个元素仅有单一的 z-index,需要另找机制决定片段的渲染顺序。因为每个 CSS Region 都会创建新的层叠上下文,所以每个片段会被单独渲染,且渲染顺序遵循常规的 CSS 渲染模型。
片段独立渲染同样适用于那些通常会作为整体渲染的元素(例如自身拥有层叠上下文或具有透明度的元素)。这些元素的每个片段都被包含在 CSS Region 创建的层叠上下文中,从而被分别渲染。
有关 CSS Region 盒子中 width 与 height 值如何解析的描述,请参阅 regions visual formatting details 小节。
当 named flows 中的元素的 flow-from 计算值为一个 <ident> 时,可能产生不合理的循环关系,例如某 named flow 包含了其自身 region chain 中的 CSS Regions。这些关系可以通过维护依赖图并使用常规的循环检测算法轻松且可靠地检测并解决。
依赖图的边满足以下条件:
如果图中出现循环,则所有在循环中、其 flow-from 计算值为某个 <ident> 的元素均不会成为 CSS Regions。
例如,如下样式会产生循环:
#id {
flow-into: foolish;
flow-from: foolish;
}
会将 #id 元素移动到一个“愚蠢的” named flow,并尝试将 #id 元素设为该“愚蠢的” named flow 的 CSS Region。随后,这个“愚蠢的” named flow 将包含它自己的区域,形成一个循环。因此 #id 元素并不会成为 CSS Region。
如果一个 CSS Region 包含了 named flow 的一个片段,并且它自身嵌套在一个碎片化上下文 [CSS3-BREAK] 中(例如在使用区域链的布局被打印时),则该 CSS Region 中包含的命名流片段的换页机会应使用标准的 碎片化规则 来确定。换句话说,每个区域框及其关联的片段应当像一个普通的 div 包含该片段内容一样进行换页。若需要,也可以在 CSS Region 上使用 avoid 换页值来进行控制。
只要不存在上述 循环检测 所破坏的循环,一个 CSS Region 就可以作为另一个独立命名流的内容的一部分。这种情况称为 嵌套区域上下文,它会影响下面描述的 可视化格式化步骤。
本节也在 [CSS3-BREAK] 中定义。如果该规范进入最后通牒并包含区域值,则此处的章节可以直接引用。
在多个区域中布局内容的用户代理必须确定内容换页发生的位置。将内容拆分成适合区域的片段的问题,与将内容拆分成页面或列的过程类似。
每一次换页都会结束当前区域的布局,并导致 named flow 中剩余的内容在区域链的后续区域中进行可视化格式化(如果存在后续区域的话)。
以下内容把 break-before、break-after 与 break-inside 三个属性从 [CSS3COL] 规范中扩展,以兼容区域。新增的取值在下文描述。
| 名称 | break-before |
|---|---|
| 值 | auto | always | avoid | left | right | page | column | region | avoid-page | avoid-column | avoid-region |
| 初始值 | auto |
| 应用于 | 块级元素 |
| 可继承 | 否 |
| 媒体 | 视觉 |
| 计算值 | 按指定值 |
| 名称 | break-after |
|---|---|
| 值 | auto | always | avoid | left | right | page | column | region | avoid-page | avoid-column | avoid-region |
| 初始值 | auto |
| 应用于 | 块级元素 |
| 可继承 | 否 |
| 媒体 | 视觉 |
| 计算值 | 按指定值 |
| 名称 | break-inside |
|---|---|
| 值 | auto | avoid | avoid-page | avoid-column | avoid-region |
| 初始值 | auto |
| 应用于 | 块级元素 |
| 可继承 | 否 |
| 媒体 | 视觉 |
| 计算值 | 按指定值 |
这些属性描述了在生成框的前/后/内部进行页面、列和区域换页的行为。这些取值已在 [CSS3COL] 中作了规范定义。
本规范为这些属性添加了以下新取值
关于区域换页的行为与页面换页的行为在 [CSS21] 中的定义完全相同。
| 名称 | region-fragment |
|---|---|
| 值 | auto | break |
| 初始值 | auto |
| 应用于 | CSS 区域 |
| 可继承 | 否 |
| 媒体 | 视觉 |
| 计算值 | 按指定值 |
region-fragment 属性控制与 named flow 关联的 最后一个区域 的行为。
如果内容能够适配 CSS Region,则此属性无任何影响;若内容无法适配,则内容会像在后续区域继续流动一样被拆分。参见 换页规则 小节。强制的区域换页优先于自然换页点。
在最后一个区域的最后一次换页之后的流动内容将不会被渲染。
region-fragment 属性不影响它所作用的区域的尺寸。
下面的代码示例演示了 region-fragment 属性的使用方式。
<style>
article {
flow-into: article-flow;
}
#region-1, #region-2 {
flow-from: article-flow;
region-fragment: break; /* or auto */
overflow: visible; /* or hidden */
}
</style>
<body>
<article>...</article>
<div id="region-1"></div>
<div id="region-2"></div>
</body>
| article with two overflowing lines |
region-fragment: break |
region-fragment: auto |
![]() |
![]() |
![]() |
region-fragment: break |
region-fragment: auto |
|
![]() |
![]() |
因为内容可能会流入多个区域,作者需要一种方式来判断是否有足够的区域容纳来自某个命名流的全部内容。这个需求在不同的显示环境下尤为重要——例如在小屏幕的移动设备上,同样的内容可能需要比大屏桌面显示器更多的区域;再比如用户改变了文字的字体大小,增大后可能需要新增区域来容纳更大的文本,缩小后则可能需要移除部分区域。
下面的 API 允许脚本获取对 NamedFlow 对象(对应于 named flow)的引用。
在 Document 接口上增加了一个属性,以便访问 named flows。
partial interface Document {
readonly attribute NamedFlowMap namedFlows;
};
namedFlows 属性位于 Document 接口上,返回文档中所有当前 named flows 的静态快照。
namedFlows 映射必须包含所有处于 CREATED 状态的 named flows。该列表不应包含处于 NULL 状态的 named flows。
NamedFlowMap 接口提供了文档中当前 NamedFlow 实例的映射。NamedFlowMap 对象是数据的快照,只读。
[MapClass(DOMString, NamedFlow)] interface NamedFlowMap {
NamedFlow? get(DOMString flowName);
boolean has(DOMString flowName);
NamedFlowMap set(DOMString flowName, NamedFlow flowValue);
boolean delete(DOMString flowName);
};
在 NamedFlowMap 对象中,映射条目为命名流标识符与对应的 NamedFlow 对象。get() 与 has() 方法在未找到对应标识符的 NamedFlow 时分别返回 null 与 false。set() 与 delete() 方法始终抛出 InvalidAccessError 异常,因为该映射为只读。NamedFlowMap 接口使用其余默认映射类的方法。
NamedFlow 接口提供了对单个 named flow 实例的表示。
NamedFlow 接口可用于多种目的。例如,getRegionsByContent() 方法可以帮助实现书签功能:脚本能够找到显示特定锚点的 CSS Regions 并将其滚动至视图中。
同样,作者可以使用该接口检查所有内容是否已经装入现有区域。如果已全部装入,则 overset 属性的值应为 false。
interface NamedFlow : EventTarget {
readonly attribute DOMString name;
readonly attribute boolean overset;
sequence<Region> getRegions();
readonly attribute short firstEmptyRegionIndex;
sequence<Node> getContent();
sequence<Region> getRegionsByContent(Node node);
};
name 属性返回该 NamedFlow 实例的名称。
overset 属性在以下情况返回 true:存在 named flow 片段无法容纳在关联的区域链中(包括区域链为空但仍有流片段的情况)。否则返回 false。
getRegions() 方法返回与该 named flow 关联的 region chain 中所有区域的序列。返回值为文档顺序的静态序列。
firstEmptyRegionIndex 表示区域链中第一个 regionOverset 为 empty 的区域索引。如果所有区域的 regionOverset 为 fit 或 overset,则该属性值为 -1。若区域链为空,同样返回 -1。
getContent() 方法返回一个有序集合,包含构成该 named flow 的节点。返回的列表是调用时 named flow 内容的静态快照,仅包括通过 flow-into 属性移动到该流的内容,不包括其子代(除非子代也被移动到该流)。
getRegionsByContent() 方法返回包含目标内容节点(若该节点直接属于该 named flow 或其祖先属于该流)所在的所有区域的序列。否则返回空序列。返回值为文档顺序的静态序列。
named flow 的状态包括:
NULL:named flow 不含任何内容,也没有区域链。CREATED:named flow 包含内容或拥有区域链。每个 NamedFlow 对象都是实时的:即使对应的 named flow 已经转入 NULL 状态,它仍然代表同名的流。
Region 接口是一个 补充接口,所有实现中可能成为 CSS Regions 的对象( Elements、伪元素或其他 CSS 构造如 slots)必须实现该接口。
[NoInterfaceObject]
interface Region {
readonly attribute DOMString regionOverset;
sequence<Range>? getRegionFlowRanges();
};
Element implements Region;
overflow 属性可用于控制溢出内容的可见性,而 region-fragment 属性决定是否在最后一个区域的溢出内容上进行碎片化。如果 named flow 没有任何内容,则与之关联的所有区域的 regionOverset 属性应返回 empty。若流中有内容但这些内容未生成任何可视化框,则关联的首个区域的 overset 属性应返回 fit。
getRegionFlowRanges() 方法返回一个 Range 实例数组,每个实例对应于该区域内布局的 named flow 片段。如果区域因太小而未收到任何片段,则返回单个 Range,其 startContainer 与 startOffset 与 endContainer、endOffset 相同,因而该 Range 为折叠状态(collapsed 为 true)。若该区域是 region chain 的首个区域,则 startContainer 为 named flow 中的第一个 Node,startOffset 为 0。若它是链中的最后一个(但不是唯一的)区域,则 startContainer 与 startOffset 与前一个区域的 endContainer、endOffset 相同。当对象不再是(或已经不再是)区域时,方法返回 null。
一个 Region 实例可能代表一个已不再是区域的对象。例如,当对应的伪元素、元素或其他构造上的 flow-from 属性被设为 none,但脚本仍持有该 Region 对象的引用时,就会出现这种情况。
NamedFlow 对象是 EventTargets,在相应触发条件下会分发以下事件。这些事件为异步事件,在 区域可视化格式化 步骤的结束时触发。
当命名流的碎片化(包括任何 overset 片段)在其区域链中发生变化时,会分发 regionfragmentchange 事件。
| 类型 | regionfragmentchange |
|---|---|
| Interface | UIEvent(参见 [DOM-LEVEL-3-EVENTS]) |
| 同步 / 异步 | 异步 |
| 冒泡 | No |
| 目标 | NamedFlow |
| 可取消 | 是 |
| 默认操作 | none(无) |
| 上下文信息 |
|
当命名流的区域链中任意 regionOverset 值改变(包括添加或移除区域)时,会分发 regionoversetchange 事件。
| 类型 | regionoversetchange |
|---|---|
| Interface | UIEvent(参见 [DOM-LEVEL-3-EVENTS]) |
| 同步 / 异步 | 异步 |
| 冒泡 | No |
| 目标 | NamedFlow |
| 可取消 | 是 |
| 默认操作 | none(无) |
| 上下文信息 |
|
getClientRects() 与 getBoundingClientRect()CSSOM View 模块定义了用户代理如何为元素(getBoundingClientRect())以及其生成的盒子(getClientRects())计算包围盒矩形。
此定义同样适用于在命名流通过区域链流动时可能产生的多个盒子。getClientRects() 方法返回在不同区域中布局的每个元素碎片生成的盒子列表。getBoundingClientRect() 方法的行为保持与 CSSOM View 模块 中的规范一致,计算结果基于 getClientRects() 返回的矩形集合。
offsetTop、offsetLeft、offsetWidth、offsetHeight 与 offsetParent在 named flow 中布局的元素的 offset 属性 计算遵循 规范 [CSSOM]。为这些算法的目的,布局在 named flow 中的元素对应的“第一个 CSS 布局盒”指的是该元素在第一个进入的区域中生成的盒子。在 offsetParent 的计算中,最近的祖先搜索会直接从顶层的命名流元素跳到 body 元素。
一个 多列 [CSS3COL] 元素可以被指定到一个 region chain。该元素会成为与相应 named flow 关联的区域链的一部分,并依据多列规范 [CSS3COL] 将其内容碎片流经各列。特别地,当计算与 named flow 关联的多列元素的 流片段高度 时,会遵循 column-fill 属性([CSS3COL])来平衡各列中的内容片段。
多列区域的溢出大体上遵循与其他 CSS Regions 相同的规则。如果命名流的剩余内容无法容纳在多列区域中,则剩余内容会继续流入后续的区域链。但若多列区域是 region chain 中的最后一个区域,则必须遵循 溢出列规则([CSS3COL])。
以下示例
<style>
article {
flow-into: article-flow;
}
#multi-col {
column-count: 2;
flow-from: article;
height: 6em;
column-gap: 1em;
}
#remainder {
flow-from: article;
height: auto;
}
</style>
<body>
<article>...</article>
<div id="multicol"></div>
<div id="remainder"></div>
</body>
在渲染上等价于,例如
<style>
article {
flow-into: article-flow;
}
#flex {
display: flex;
flex-pack: justify;
height: 6em;
}
#flex > div {
flow-from: article;
width: calc(50% - 0.5em);
}
#remainder {
flow-from: article;
height: auto;
}
</style>
<body>
<article>...</article>
<div id="flex">
<div />
<div />
</div>
<div id="remainder"></div>
</body>
作者可以使用视觉标记来提示内容正通过区域链流动。例如,标记 “continued below” 能在 CSS Region 末尾清晰地表明后面还有内容,用户只需向下滚动即可看到。
“::before” 与 “::after” 伪元素(参见 [SELECT])允许内容作者使用此类标记来标记区域的起始和结束。
区域由 CSS 布局,并参与普通盒模型以及像弹性盒子([CSS3-FLEXBOX])等其他布局模型。然而,区域并不像其他盒子那样布局其后代内容,而是布局其 named flow 的一个片段。
本节描述了布局 区域 与将 named flow 内容布局到区域中的模型。文中采用水平书写模式的描述,使用 width 表示逻辑宽度(或度量),height 表示逻辑高度(或范围),参见 CSS Writing Modes 模块 [CSS3-WRITING-MODES] 中的定义。若需在竖排模式下使用此模型,请参考该规范中描述的 竖排布局原则。
“::before” 内容在任何来自流的其他内容之前布局于区域内。
“::after” 内容在将流片段内容布局进 RFCB 之后布局于区域内。随后,会从流片段中移除内容以容纳 “::after” 内容。这里的“容纳”指的是在不导致区域溢出的前提下布局 “::after”。
若没有足够空间容纳 ::before 内容、在移除全部流片段后容纳 ::after 内容,或两者的组合,则 ::before 和/或 ::after 内容会在该区域中溢出。
区域盒子布局以下盒子:
::before 与 ::after 伪元素生成的盒子(若存在)。布局一个 region 盒子遵从与其他 块容器盒子 相同的处理规则。
RFCB 是一个 块容器盒子,其计算的 width 为 auto,且其使用的 height 按下文所述进行解析。
因为 RFCB 是块容器盒子,::before 与 ::after 盒子也将是块容器,尽管它们的内容可以在这些盒子内部以行内方式呈现。
在涉及区域的文档可视化格式化的多个阶段,需要解析 RFCB 与区域的使用 width。所有情况下,解析均遵循 计算宽度和外边距的规则(见 [CSS21])。有时,解析使用的 width 需要测量内容的 min-content 与 max-content(如 CSS Writing Modes 模块 [CSS3-WRITING-MODES] 中定义)。**对 RFCB 而言,这些度量基于*整个*关联的 named flow 内容进行。
因此,属于同一 named flow 的所有区域的 RFCB 共享相同的 min-content 与 max-content 度量。
此做法与 碎片化的盒模型([CSS3-BREAK])保持一致。
对包含 named flows 且布局于区域中的文档进行格式化需经历三步:
概念上,解析 flow fragment height 是一个两阶段的过程。
文档使用所有 RFCB 的 used 高度为零进行布局。在此阶段,named flows 的内容尚未在 regions 中布局。此阶段产生文档中所有区域及其 RFCB 的已解析位置与尺寸。
named flows 在 regions 中布局。用户代理根据流的剩余部分以及 碎片化规则 为 RFCB 解析 flow fragment height。此过程会考虑诸如 height 或 max-height 等约束,详见 CSS 2.1 中的 计算高度和外边距(参照 块级非替换元素在正常流中的计算 与 复杂情况)。在此阶段,生成的内容会按照前述 处理模型 进行布局。
在嵌套区域上下文中,此阶段将触发对所有内部命名流的第 1 步的开始,只要这些内部流的区域包含在外部命名流中。内部流的第 1 步必须递归完成后,外部流的第 1 步才算完成。
在此步骤中,文档按照常规 CSS 布局规则进行布局。
如果需要测量内容以解析区域框的已用width,则该值按RFCB 宽度解析章节中描述的方式解析。
如果需要测量内容以解析 RFCB 的已用height(例如当区域框是绝对定位时),则在第 1 步中解析的flow fragment height用于 RFCB 的垂直内容测量。
本步骤结束时,区域已布局完成,准备好接收其关联的named flows的内容。
在此最后一步,named flows的内容与生成的内容框一起布局到各regions的 RFCB 中。
RFCB 的已用height的解析方式保证区域框的普通流中的任何盒子都不会溢出该区域框。换句话说,RFCB 盒子会在垂直方向伸展,以容纳尽可能多的流内容,且不会导致溢出,同时考虑fragmentation rules和生成的内容盒子。
在此阶段,生成的内容按照本文件前面描述的规则进行布局。
在nested region context中,此步骤将对所有内部named flows的第 2 步进行触发,只要这些内部流的区域包含在外部named flow中。内部区域的分块可能在它们被布局到外部区域链时产生。一旦外部命名流的第 3 步完成,内部命名流的第 3 步递归地开始。
当某个命名流的第 3 步完成后,会检查named flow events的条件;如果触发条件满足,则在此时分派相应事件。
自动尺寸区域的解析模型在某些情况下会导致流内容出现超限或不足,即无法紧密适配。该模型旨在防止布局模型出现循环依赖。实现可以决定采用额外的布局步骤,以确保即使在极端情况下也能向用户完整显示所有流内容。
解析 RFCB 的height的过程以及用于布局包含区域和named flows的文档的三步流程,都是对布局应产生的结果的概念性描述,实现应在可能的情况下进行优化,以减少所需的步骤和阶段数量。
本节是非规范性的。
本示例考虑了一个文档,其中内容在三个区域之间流动,且区域框与普通文档内容交叉出现。
<style>
article {
flow-into: article;
}
#rA, #rB, #rC {
flow-from: article;
height: auto;
margin: 1em 1em 0em 1em;
padding: 1em;
border: 3px solid #46A4E9;
}
#rA {
width: auto;
}
#rB {
float: left;
width: 15em;
max-height: 150px;
}
#rC {
float: right;
width: 12em;
}
#main-flow {
padding: 0em 1em 0em 1em;
}
</style>
<body>
<article>
<p style="break-after:region;">I am not a ... </p>
<p>...</p>
</article>
<div id="rA"></div>
<div id="rB"></div>
<div id="rC"></div>
<div id="main-flow">
<p>Lorem ipsum dolor ...</p>
</div>
</body>
下面的章节和图示说明了可视化排版过程的中间结果。下文中,RFCB-A、RFCB-B 和 RFCB-C 分别指代区域 rA、rB、rC 的 RFCB。
依据第 1 步阶段 1 的规则,RFCB 的计算得到的autowidth值按照常规CSS layout rules解析为已用值,即它们会伸展至其包含块内容盒的宽度。
rB 内容盒。rC 内容盒。同样依据第 1 步阶段 1 的规则,RFCB 的height属性的已用值全部为零。
从概念上看,这会产生如下所示的布局。
在第 1 步的第二阶段,命名流在各regions中布局,并计算落在每个 RFCB 中的每个片段的高度。
用户代理将在 RFCB-A 的已用width所定义的区域中尽可能多地布局流内容。rA 的高度计算为auto,且对 RFCB-A 的高度没有垂直最大限制。然而,由于在“article”命名流的第一段之后存在换页(break),仅将该第一段布局在 RFCB-A 中,FH-A(即 RFCB-A 的流片段高度)通过在已用width下布局这段文字得到解析。
此时,用户代理在 RFCB-B 中尽可能多地布局剩余的流内容。由于 rB 的计算max-height为 “150px”,用户代理仅在 RFCB-B 的已用width下布局 “article” 命名流,直至继续布局会导致 RFCB-B 溢出 rB 的盒子为止。RFCB-B 的片段高度解析为:FH-B(150px)。
最后,用户代理在 RFCB-C 中布局剩余的流内容。由于 rC 没有其他约束且没有区域换页,剩余内容会在 RFCB-C 的已用width下布局,从而得到解析后的流片段高度:FH-C。
RFCB-A、RFCB-B 和 RFCB-C 的已用width如前一步所述解析。但高度的解析方式不同。
解析 rA 的高度需要内容测量,即 FH-A(RFCB-A 的流片段高度)。
rB 的高度来源于先计算其内容测量,然后应用rules for max-height。此处垂直内容测量的值为 FH-B。随后在考虑边距、内填充和边框后,依据max-height规则,rB 的已用height解析为 LH-B(150px)。
rC 盒子的高度来源于计算其内容测量:FH-C 成为 rC 的已用height。
在此最后一步,article named flow 在其region chain中布局。每个 RFCB 的已用width按上文第 1 步的方式解析。
RFCB 的已用height是通过在区域内尽可能多地布局内容且不溢出其内容盒,并遵循fragmentation rules而得出的结果。
由于 RFCB 的已计算width未改变,且所应用的分块规则与阶段 1、步骤 2 相同,RFCB-A、RFCB-B 和 RFCB-C 的已用height分别为 LH-A、LH-B 和 LH-C。
在某些情况下,步骤 3 中解析得到的 RFCB 已用高度可能与步骤 1 阶段 2 计算的流片段高度不同。
CSS Regions 模块并不改变文档树中事件的正常处理。特别是,如果某个事件发生在属于named flow的元素上,则该事件的
这意味着在大多数情况下CSS Regions不会接收到作用于其命名流内容的用户事件。针对命名流内容的事件处理器可以调用getElementsFromPoint() [CSSOM-VIEW] 来查找用户事件发生所在的 CSS Region。未来的 CSS-UI 版本可能会提供更通用的用户事件冒泡解决方案,以在事件坐标处获取元素堆栈。
本规范与参考章节中描述的其他规范相关,此外还关联以下规范:
::region() 改为 ::region。NamedFlowCollection 更名为 NamedFlowMap。run‑in 的提及,并澄清 ::before 与 ::after 块容器。NamedFlow 时,将 NamedFlowCollection 的 getter 改回返回 null。NamedFlow.getContent() 的返回类型从 NodeList 改为 sequence<Node>。@region 规则改为 ::region() 功能性伪元素。CSSRegionStyleRule(见上文)。flow-into 中添加了 content 与 element 关键字。regionoversetchange 事件。regionlayoutupdate 重命名为 regionfragmentchange。offsetParent 的交互方式。flow-from 时伪元素生成的变化。regionlayoutupdate 的大小写改为与 [DOM-LEVEL-3-EVENTS] 中的其他事件一致。flow-from 与 flow-into 情形的章节。regionLayoutUpdate 事件添加了时序。content 与 flow-from 之间的交互。NamedFlowCollection 的 getter 改为在不存在 NamedFlow 时返回 undefined。region-overflow 属性改为 region-fragment。Region 接口中移除异常。NamedFlowCollection 从实时改为静态快照。NamedFlow 改为继承自 EventTarget。Region 接口中移除 flowFrom,并将方法名改为 getComputedRegionStyle()。Region 接口现为补充接口,并带有 [NoInterfaceObject] 扩展属性。regionLayoutUpdate 的注记。Document.getFlowByName(),改用 NamedFlowCollection.namedItem()。NULL NamedFlow 将 overset 改为 false。regionLayoutUpdate 改为不冒泡。较早的更改日志已在 CSSWG wiki 上归档。
编辑们感谢 CSS 工作组对本规范起草提供的反馈与帮助。
此外,编辑还要感谢以下人士对 CSS Regions 的构思、开发及规范审查过程中的贡献:
Erik Arvidsson, Tab Atkins, Catalin Badea, Mihai Balan, Andrei Bucur, Razvan Caliman, Alexandru Chiculita, Phil Cupp, Arron Eicholz, John Jansen, CJ Gammon, Dimitri Glazkov, Daniel Glazman, Arno Gourdol, Catalin Grigoroscuta, David Hyatt, Brian Heuston, Ian Hickson, Jonathan Hoersch, Michael Jolson, Brad Kemper, Håkon Wium Lie, Kang‑Hao (Kenny) Lu, Mihai Maerean, Markus Mielke, Robert O’Callahan, Edward O’Connor, Mihnea Ovidenie, Virgil Palanciuc, Olga Popiv, Christoph Päper, Anton Prowse, Peter Sorotokin, Elliott Sprehn, Radu Stavila, Christian Stockwell, Eugene Veselov, Boris Zbarsky, Stephen Zilles and the CSS Working Group members.
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 邮件列表。
| 名称 | 值 | 初始值 | 应用于 | 继承 | 百分比 | 媒体 | 计算值 |
|---|---|---|---|---|---|---|---|
| flow-into | none | <ident> [element|content]? | none(无) | All elements, but not pseudo-elements such as ::first-line, ::first-letter, ::before or ::after. | 否 | 视觉 | 按指定值 | |
| flow-from | <ident> | none | inherit | none(无) | Non-replaced block containers. This might be expanded in future versions of the specification to allow other types of containers to receive flow content. | 否 | 视觉 | 按指定值 | |
| break-before | auto | always | avoid | left | right | page | column | region | avoid-page | avoid-column | avoid-region | auto | 块级元素 | 否 | 视觉 | 按指定值 | |
| break-after | auto | always | avoid | left | right | page | column | region | avoid-page | avoid-column | avoid-region | auto | 块级元素 | 否 | 视觉 | 按指定值 | |
| break-inside | auto | avoid | avoid-page | avoid-column | avoid-region | auto | 块级元素 | 否 | 视觉 | 按指定值 | |
| region-fragment | auto | break | auto | CSS 区域 | 否 | 视觉 | 按指定值 |