1. 引言
本规范扩展了 [CSS-OVERFLOW-3]。 它包含多个主要部分:
- 溢出滚动和裁剪控制
-
本节定义了对 overflow-* 属性的相对简单的扩展,在第3级中。
- 自动省略号。
-
本节定义了对 *-ellipsis 属性的某些实验性扩展,在第3级中。
- 溢出重定向
-
本节定义了一种高度实验性、探索性的新模型 通过将溢出重定向到新生成的 分片容器 来处理溢出。
注意: 在撰写本文时,[CSS-OVERFLOW-3] 尚未完全定稿。 为避免意外的分歧和维护成本, 本规范作为 CSS 溢出第3级的增量规范编写。 一旦第3级规范最终确定, 其内容将被整合到本规范中, 然后本规范将替代它。 在此之前,本规范仅包含对第3级的补充和扩展。
1.1. 值定义
本规范遵循 CSS 属性定义约定 来自 [CSS2],使用 值定义语法 来自 [CSS-VALUES-3]。 本规范中未定义的值类型定义于 CSS 值与单位模块 [CSS-VALUES-3] 中。 与其他 CSS 模块的组合可能会扩展这些值类型的定义。
除了在各自定义中列出的特定于属性的值之外, 本规范中定义的所有属性 还接受 CSS-wide 关键词 作为其属性值。 为了可读性,这些关键词没有被重复明确列出。
1.2. 模块交互
此模块扩展了 [CSS-OVERFLOW-3] 中定义的功能。
2. 溢出概念和术语
当内容最终确定时,复制 第3级内容。
3. 滚动和裁剪溢出
当内容最终确定时,复制 第3级内容。
3.1. 管理溢出:overflow-x、overflow-y 和 overflow 属性
本级扩展了 overflow-x 和 overflow-y 属性 (以及 overflow 的简写) 适用于 替换元素。
对于 替换元素, 所有计算值的 使用值 除了 visible 之外都是 clip。 主机语言应定义 UA 样式表 规则 为此类元素应用默认值 clip 并将其 overflow-clip-margin 设置为 内容框。
注意: 将 overflow 应用于 替换元素 是为了允许图像在其有效布局框外绘制效果; 推荐的 UA 样式表规则是为了确保它们的默认行为。 参见 Issue 7059 和 Issue 7144 中的讨论。 这是与 CSS2.1 的区别,并且有风险。
将 overflow 应用于 替换元素 仍在开发中。[Issue #7144]
3.2. 扩展裁剪边界:overflow-clip-margin-* 属性
名称: | overflow-clip-margin-top, overflow-clip-margin-right, overflow-clip-margin-bottom, overflow-clip-margin-left, overflow-clip-margin-block-start, overflow-clip-margin-inline-start, overflow-clip-margin-block-end, overflow-clip-margin-inline-end |
---|---|
值: | <visual-box> || <length [0,∞]> |
初始值: | 0px |
适用于: | 应用 overflow 的盒子 |
继承: | 否 |
百分比: | 参见各个属性 |
计算值: | 计算的 <length> 和 <visual-box> 关键字 |
动画类型: | 如果 <visual-box> 值匹配,则按计算值;否则为离散 |
规范顺序: | 按语法 |
逻辑属性组: | overflow-clip-margin |
名称: | overflow-clip-margin, overflow-clip-margin-inline, overflow-clip-margin-block |
---|---|
值: | <visual-box> || <length [0,∞]> |
初始值: | 0px |
适用于: | 应用 overflow 的盒子 |
继承: | 否 |
百分比: | 参见各个属性 |
计算值: | 参见各个属性 |
动画类型: | 参见各个属性 |
规范顺序: | 按语法 |
这些属性及其速记形式 定义了盒子的 溢出裁剪边缘, 即盒子的内容在被裁剪前允许在其边界之外绘制的精确范围 由效果(例如上文提到的 overflow: clip)定义为裁剪到盒子的 溢出裁剪边缘。 速记和长手写的关系 类似于 margin, 但请注意,速记具有受限的语法。
值定义如下:
- <visual-box>
-
指定用于作为 溢出裁剪边缘 原点的盒子边缘, 即当指定偏移量为零时。
如果省略, 对于非 替换 元素,默认为 padding-box, 对于 替换 元素,默认为 content-box。
将 overflow-clip-margin 应用于 替换元素 仍在开发中。[Issue #7144]
- <length [0,∞]>
-
指定的偏移量决定了 从指定的盒子边缘扩展 溢出裁剪边缘 的量 负值无效。 如果省略,默认为零。
溢出裁剪边缘 在角落的形状 与 外部盒子阴影 使用相同的累积偏移量扩展的扩展半径形状完全相同, 参见 CSS Backgrounds 3 § 4.2 角落形状 和 CSS Backgrounds 3 § 6.1.1 阴影形状、扩展和去除, 特别注意边框边缘之外的扩展公式 border edge。
注意: 此属性对具有 overflow: hidden 或 overflow: scroll 的盒子无效, 这些盒子未定义为使用 溢出裁剪边缘。
4. 自动省略号
4.1. 内联溢出省略号:text-overflow 属性
名称: | text-overflow |
---|---|
值: | [ clip | ellipsis | <string> | fade | <fade()> ]{1,2} |
初始值: | clip |
适用于: | 块容器 |
继承: | 否 |
百分比: | 参考行框的宽度 |
计算值: | 按指定计算,长度转为绝对值 |
规范顺序: | 按语法 |
动画类型: | 按计算值类型 |
该部分可能需要 与 [CSS-OVERFLOW-3] 重新同步。
此属性指定当内联内容溢出 其行框边缘时的渲染方式, 在其块容器元素(“块”)的内联进程方向上, 且该块具有 overflow 属性,但不是 visible。
尽管此属性不继承, 但生成的匿名块容器框以 建立行框的内联格式化上下文(参见 块容器) 被忽略, 应用的属性值是非匿名框上的值。这可以在 示例 7 中的“嵌套段落”部分看到: 即使单词“NESTED”包裹在一个匿名块容器中, 其 text-overflow 属性具有初始值, 但它被省略了。
例如,当内容被阻止换行时(如由于
或单个单词过长无法适配)会导致文本溢出。
值的含义如下:
- clip
- 裁剪溢出其块容器元素的内联内容。 字符可能只会部分渲染。
- ellipsis
- 渲染一个省略号字符 (U+2026) 来表示被裁剪的内联内容。 实现可以替换为更适合语言、脚本或书写模式的 省略号字符, 或在省略号字符不可用时显示三个点 "..."。
- <string>
- 渲染给定的字符串以表示被裁剪的内联内容。 在双向文本处理上,给定的字符串被视为独立段落。
- fade( [ <length> | <percentage> ] )
-
裁剪溢出行框的内联内容。
字符可能只会部分渲染。
此外,UA 必须在行框边缘附近应用淡出效果,
在边缘处达到完全透明。
我们是否需要定义 淡出效果的计算方式 以使得淡出效果在不同浏览器中一致? 它可能应该类似于 mask-image: linear-gradient(to right, rgba(0,0,0,1), rgba(0,0,0,0)), 只是仅应用于行框的相关部分。
参数决定淡出效果应用的距离。 <percentage> 相对于行框宽度进行解析。 值小于 0 的部分将裁剪为 0。 超过行框宽度的值将裁剪为行框宽度。
如果行框过短 无法显示所需长度的淡出效果, 我们应该去掉效果, 还是将应用距离缩短直到适合, 还是裁剪掉淡出的尾端?
我们应该如何处理 溢出行框的内容, 或与其重叠的内容? 淡出效果应该应用于行的逻辑内容, 还是应用于行框的物理区域, 还是两者的交集?
- fade
- 与 fade() 相同, 但淡出效果的应用距离 由 UA 决定。1em 是一个合理的建议值。
在此属性定义中使用术语“字符”是为了提高可读性,意为“字形簇”,实现时请参考 [UAX29]。
如果只有一个值, 它仅适用于 行尾行框边缘。 如果有两个值, 第一个值适用于 行左侧边缘, 第二个值适用于 行右侧 边缘。 术语行尾、行左侧和行右侧在 [CSS-WRITING-MODES-3]中定义。
注意: 使用 行左侧 和 行右侧 而不是 开始 和 行尾 是有意的, 以方便使用定向字符(如箭头)。
对于省略号 和字符串值, 实现必须在行的适用边缘处隐藏字符和 原子内联级元素,以适应省略号/字符串,并 将省略号/字符串紧邻剩余内联内容的适用边缘处。 行中的第一个字符或原子内联级元素 必须被裁剪,而不是省略。
双向文本省略号 示例
这些示例展示了在双向文本情况下,哪些字符会被隐藏 以为省略号腾出空间: 那些在行的视觉边缘的字符。示例 CSS:
div {
font-family : monospace;
white-space : pre;
overflow : hidden;
width : 9 ch ;
text-overflow : ellipsis;
}
示例 HTML 片段、渲染和浏览器:
HTML | 参考渲染 | 您的浏览器 |
---|---|---|
|
123456 ם…
| |
|
…456 שלום
|
省略号细节
- 省略号只影响渲染,不能影响布局 也不能影响指针事件的分发: UA 应该将任何指针事件分发到被省略的元素, 就像 text-overflow 被设置为 none 一样。
- 省略号根据块的样式和基线对齐进行渲染。
- 省略号发生在相对定位和其他图形变换之后。
- 如果没有足够的空间显示省略号, 则裁剪省略号的渲染 (与行中的中性字符 使用 text-overflow:clip 值时会被裁剪的方向相同)。
用户与省略号的交互
- 当用户与内容交互时 (例如编辑、选择、滚动), 用户代理可以将 省略号、字符串值、fade 或 fade() 视为 text-overflow:clip。
- 选择省略号应该同时选择被省略的文本。 如果选择了所有被省略的文本, UA 应该显示省略号的选择。 对部分选择被省略文本的行为由 UA 决定。
text-overflow 示例
这些示例演示了为一个包含超出其尺寸的文本的块容器元素设置 text-overflow 属性:
示例 div 的 CSS:
div {
font-family : Helvetica, sans-serif;
line-height : 1.1 ;
width : 3.1 em ;
border : solid .1 em black;
padding : 0.2 em ; margin : 1 em 0 ;
}
示例 HTML 片段、渲染和您的浏览器:
HTML | 示例渲染 | 您的浏览器 |
---|---|---|
|
CSS IS AWESOME, YES
| |
| ||
| ||
| ||
|
注意: 省略号的位置取决于块的 方向 属性。
例如,设置了 overflow:hidden 且使用从右到左(rtl)
的块会在 左边
裁剪内联内容,
因此会在 左边放置一个省略号以表示被裁剪的内容。
省略号与滚动界面的交互
本部分适用于设置了非 text-overflow:clip (非裁剪 text-overflow) 且设置了 overflow:scroll 的元素。
当具有非裁剪 text-overflow 的元素在文本的内联进程方向上有滚动溢出时, 且浏览器提供了滚动机制 (例如元素上的滚动条, 或触摸界面以滑动滚动等), 存在一些额外的实现细节以提供更好的用户体验:
当元素被滚动时(例如通过用户操作或 DOM 操作), 更多的元素内容会被显示。 text-overflow 的值不应影响 是否显示更多的元素内容。 如果设置了非裁剪 text-overflow, 那么当更多的内容滚动显示时, 实现应显示能够适应的任何额外内容, 只裁剪本应被裁剪的内容 (或为省略号/字符串腾出空间的内容), 直到元素滚动到显示内容的边缘, 此时应显示内容而不是省略号/字符串。
示例 CSS:
div.crawlbar {
text-overflow : ellipsis;
height : 2 em ;
overflow : scroll;
white-space : nowrap;
width : 15 em ;
border : 1 em solid black;
}
示例 HTML 片段:
< div class = "crawlbar" >
CSS is awesome, especially when you can scroll
to see extra text instead of just
having it overlap other text by default.
</ div >
演示示例 CSS 和 HTML:
当某些内容滚动到视图中时, 可能会有其他内容从另一侧滚动出视图。 如果这些内容的块容器元素是同一个进行滚动的元素, 且 text-overflow 的计算值有两个值, 且应用于起始边缘的值为非裁剪值, 则实现必须在 被裁剪的内容处渲染省略号/字符串, 其细节与上文值定义中的描述相同, 只是省略号/字符串绘制在块的 起始方向 (而非 终止) 取决于 direction 属性。
当内容滚动时, 实现可能会调整省略号/字符串的渲染 (例如对齐到框边缘而不是行边缘)。
text-overflow: ellipsis ellipsis
:
如果没有足够的空间同时显示起始 和终止省略号/字符串, 则只应渲染终止的省略号/字符串。
4.2. 指示块轴溢出:block-ellipsis 属性
名称: | block-ellipsis |
---|---|
值: | none | auto | <string> |
初始值: | none |
适用于: | 块容器 |
继承: | 是 |
百分比: | 不适用 |
计算值: | 指定值 |
规范顺序: | 根据语法 |
动画类型: | 离散 |
此属性允许在(强制或非强制的)区域断开前的最后一个行框中插入内容,以指示被截断/中断的内容的连续性。 它只影响由块容器本身直接包含的行框, 但由于它是继承的,除非被覆盖,否则将影响后代元素的行框。 如果盒子中在 区域断开前没有包含任何行框,则此属性无效。
注意: 请参阅附录A:溢出的重定向,了解如何生成带有此类 区域断开的盒子。
插入的内容称为 块溢出省略号。 值的含义如下:
- none
- 渲染不受影响。
- auto
- 渲染一个省略号字符 (U+2026)—或者更符合排版习惯的等效字符—作为在受影响行框末尾的 块溢出省略号。 用户代理应使用内容语言、书写系统和 书写模式的约定来确定最合适的省略号字符串。
- <string>
- 渲染指定的字符串 作为在受影响行框末尾的 块溢出省略号。 如果字符串过长,用户代理可以截断该字符串。
当 block-ellipsis 不是 none时, 块溢出省略号 字符串 作为匿名内联被包装并放置在行框的末尾, 作为 块容器的 根内联框的直接子元素, 减少行框中留给其他内容的空间。 该内联元素被分配了 unicode-bidi: plaintext 和 line-height: 0,并在最后一个仍能容纳整个 块溢出省略号 的 软换行机会(参见 [CSS-TEXT-3])后放置。 出于这个目的,由 overflow-wrap 添加的 软换行机会 将被忽略。 如果这导致行框中的所有内容都被移位, 则该行框被认为包含 支撑元素,如 CSS 2.1 § 10.8.1 前导和半前导中定义的那样。 文本 对齐和对齐方式 在放置后进行, 并将插入的 块溢出省略号 与行的其余内容一起进行测量。
注意: 设置 块溢出省略号 的 line-height 为 0,确保插入它不会导致行高增加, 否则可能会引发重新布局甚至循环。 这几乎相当于在绘制时插入 块溢出省略号,不同之处在于它仍然参与对齐和对齐方式。 缺点是 块溢出省略号 中异常高/深的字符可能会溢出。
块溢出省略号 不得包含在 ::first-letter 或 ::first-line 伪元素中。
如果在 分片容器 中有后续片段接收内容, 则由 块溢出省略号 移位的内容必须推送到该 分片容器。
UA 必须将 块溢出省略号 视为不可拆分的字符串, 如果 块溢出省略号 的任何部分溢出, 则将其视为 可滚动溢出, 并受 text-overflow 属性的影响。
块溢出省略号 不捕获事件: 指针事件会被分发到其下方的内容。
它对盒子的固有尺寸没有影响: 其 最小内容 和 最大内容 尺寸的计算与 block-ellipsis 设置为 none 时完全相同。
注意: 未来的规范可能会扩展此功能, 例如通过提供 ::ellipsis 伪元素 来设置文本样式, 或通过选择块的子元素 作为内联或块级指示符使用 (在这种情况下,它可以捕获事件)。
5. 溢出分片
5.1. 限制可见行数:line-clamp 简写属性
名称: | line-clamp |
---|---|
值: | none | <integer [1,∞]> <'block-ellipsis'>? |
初始值: | none |
适用于: | 参见各属性 |
继承: | 参见各属性 |
百分比: | 不适用 |
计算值: | 参见各属性 |
动画类型: | 参见各属性 |
规范顺序: | 根据语法 |
line-clamp 属性是 简写,用于 max-lines、block-ellipsis 和 continue 属性。
目前,建议实验性实现遵循此简写及其长属性定义的完整行为,但只向开发者公开简写形式。 这是为了进一步调整,尤其是对长属性及其值的潜在重命名。
它允许将块容器的内容限制为指定的行数; 剩余内容将被分片并且不会渲染或测量。 可选地,它还允许在最后一个行框中插入内容,以指示被截断/中断的内容的连续性。
值的含义如下:
- none
- 设置 max-lines 为 none,continue 为 auto, 并且 block-ellipsis 为 none。
- <integer [1,∞]> <block-ellipsis>?
- 设置 max-lines 为指定的 <integer>,continue 为 discard, 而 block-ellipsis 属性的第二个部分为值,或者如果省略则为 auto。
有关此机制的详细信息,请参见相应的长属性。
li{ line-clamp : 5 "… (continued on next page)" ; } strong{ display : block; text-transform : uppercase; }
< li >< a href = "cheese-is-milk" > < strong > 奶酪实际上是由牛奶制成的!</ strong > 世界宽网新闻记者发现了奶酪的秘密。 追踪错综复杂的官僚机构和影子公司, 我们的调查记者团队追踪到了卡门培尔奶酪的来源。</ a ></ li >
示例渲染:
+---------------------------------------+ | 奶酪实际上是由牛奶制成的! | | 世界宽网新闻记者发现了奶酪的秘密。 | | 追踪错综复杂的官僚机构和影子公司, | | 我们的调查记者团队追踪到了卡门培尔奶酪的 | | 来源。 (continued on next page) | +---------------------------------------+
5.1.1. 旧版兼容性
为了兼容旧版内容,支持 line-clamp 的用户代理(UA)还必须支持 -webkit-line-clamp 属性 以及 -webkit-discard 值,用于 continue 属性。
名称: | -webkit-line-clamp |
---|---|
值: | none | <integer [1,∞]> |
初始值: | none |
适用于: | 参见各属性 |
继承: | 参见各属性 |
百分比: | 不适用 |
计算值: | 参见各属性 |
动画类型: | 参见各属性 |
规范顺序: | 根据语法 |
名称: | continue |
---|---|
新增值: | -webkit-discard |
类似于 line-clamp,-webkit-line-clamp 也是 max-lines、continue 和 block-ellipsis 的简写, 除了以下几点不同:
-
其语法为 none | <integer [1,∞]>
-
它将 continue 设置为 -webkit-discard 而不是 discard
-
它无条件将 block-ellipsis 设置为 auto
此外,对于其 display 属性计算为 -webkit-box 或 -webkit-inline-box 的盒子的子元素(包括匿名子元素), 它的 max-lines、continue 和 block-ellipsis 的使用值 来自父盒子的计算值; 它自身这些属性的计算值被忽略。
-webkit-discard 值与 discard 表现一致, 但仅在父元素的 display 属性的计算值 为 -webkit-box 或 -webkit-inline-box,且父元素的 -webkit-box-orient 属性的计算值 为 vertical 时生效。
注意: 对于旧版 -webkit-line-clamp 属性的实现, 行为与此处规定的行为并不完全一致。 历史行为相对较为古怪且不够稳健, 例如在 这篇博客文章 中有详细说明。 当前的设计从该早期实验的错误中汲取了教训, 旨在与现有内容保持足够的兼容性, 以便最终能够将实现更改为遵循该规范行为。 如果发现需要进一步调整, 它们将被合并到该规范中。 与此同时,作者应意识到可能存在差异。
5.2. 在设置的行数之后强制换行:max-lines 属性
名称: | max-lines |
---|---|
值: | none | <integer [1,∞]> |
初始值: | none |
适用于: | 块级容器 同时也是 分割容器,捕获 区域分割 |
继承: | no |
百分比: | 不适用 |
计算值: | 关键字 none 或整数 |
规范顺序: | 根据语法 |
动画类型: | 根据计算值类型 |
此属性对不是 分割容器 的盒子没有影响,无法捕获 区域分割。
否则,如果 max-lines 的值不是 none, 在其第 N 个后代 流内 行框 之后强制进行 区域分割, 其中 N 是 max-lines 的指定值。 只有在同一 块格式化上下文 中的行框才会被计算: 在计数行框时,会跳过创建了 独立格式化上下文 的后代内容。
如果行框少于 N 个, 则 max-lines 不会引入任何 区域分割。
< div id = a > a: line 1< br > a: line 2< br > < div id = b > b: line 1< br > b: line 2< br > b: line 3< br > b: line 4< br > </ div > a: line 3< br > a: line 4< br > </ div >
示例渲染结果给定 #a
:
a: line 1 a: line 2 b: line 1 b: line 2… a: line 3…
示例渲染结果给定 #a
:
a: line 1 a: line 2 b: line 1…
注意,在第二个例子中, 元素 #b 上设置的最大 2 行未生效, 因为在该元素的第二行之前引入了强制换行。
注意: 这意味着 max-lines 对于 多列容器 没有影响, 因为它们包含的任何行框都嵌套在 独立格式化上下文 中。
仅接受正整数。 零或负整数是无效的, 必须使声明被 忽略。
注意: widows、orphans 和 break-inside 属性 不会影响由 max-lines 属性引入的强制 区域分割 的位置。
如果实现既不支持 [CSS-REGIONS-1] 也不支持 CSS Overflow 4 § 5 重定向溢出, 那么它还没有遇到过这种分割, 这将是一个新增功能。 然而,这一新增功能并不涉及引入任何 [CSS-REGIONS-1] 功能。 所需的只是:
-
能够进行分割
-
为强制分割的目的将这些分割容器归类为“第 3 类” (即非页面也非列的容器)。
5.3. 溢出内容的分割:continue 属性
名称: | continue |
---|---|
值: | auto | discard |
初始值: | auto |
适用于: | 块级容器 和 多列容器 |
继承: | no |
百分比: | 不适用 |
计算值: | 指定的关键字 |
规范顺序: | 根据语法 |
动画类型: | 离散 |
continue 属性允许作者将盒子转换为 分割容器(参见 [CSS-BREAK-3]),并指定在分割点之后的内容必须被丢弃。
此属性旨在通用化并取代
region-fragment
属性来自 [CSS-REGIONS-1]。
一旦它在该规范中足够稳定,应该从区域规范中移除 region-fragment
,并采用此属性。
- auto
-
如果盒子有超出可容纳的内容, 则根据常规规则处理多余的内容。
- discard
-
该盒子变为 分割容器,捕获 区域分割,
如果它尚未是容器。[CSS-BREAK-3]
在第一个 区域分割 之后的内容不会被渲染(见下文)。
(如果盒子是 多列容器,
则任何 溢出列 也不会被渲染。)
注意: 该 区域分割 可能是 强制分割 (例如,由 max-lines 或其他机制引起, 例如 break-before/break-after 属性), 或者是 非强制分割(例如,如果内容由于尺寸限制而会溢出此 分割容器)。 应用于其他 分割上下文 的分割(如该盒子本身的分页) 不会导致任何内容被丢弃。
注意: 此属性不会导致盒子 创建独立格式化上下文。

continue: discard | continue: auto | |
---|---|---|
overflow: visible | ![]() | ![]() |
overflow: hidden | ![]() | ![]() |
由于 continue: discard 而“未渲染”的内容将被丢弃,类似于 display: none:
-
它不会被渲染。
-
它也不会用于语音渲染。
-
它不允许用户交互。
-
确保对对象模型的影响定义清晰 [Issue #2970]
-
处于丢弃内容中的 定位元素的静态位置如何处理? 另见 Sydney F2F 会议 的讨论。 [Issue #2971]
然而,由于内在尺寸是在跨 分割容器 时计算的, 此内容将被考虑用于计算盒子的 最小内容宽度 和 最大内容宽度 内联尺寸(见 CSS 分割 3 § 5.1 在变化尺寸的分割容器中断开)。最小内容宽度 和 最大内容宽度 块级尺寸 是基于从 分割流 的开头到第一个 强制换行(如果有的话)或 分割流 末尾的内容来计算的。
注意: 对于 并行分割流 的情况, 盒子树中分割点之后的内容仍然可能被渲染, 如果它位于代表该 分割容器 结束位置的上方。
附录A: 溢出内容的重定向
本节是高度实验性的。 它记录了当前扩展 continue 属性能力的尝试, 以解决其他使用案例。 然而,它目前还没有达成共识。 在这里呈现是为了鼓励讨论, 但不推荐非实验性实现。
在CSS 1级 [CSS1] 中,放置超过元素指定大小的内容 通常是一个作者错误。 这样做会导致内容超出元素的边界, 这可能会导致 这些内容与其他元素重叠。
CSS 2级 [CSS2] 引入了 overflow 属性, 它允许作者通过滚动来处理溢出, 这意味着这不再是一个作者错误。 它还允许作者指定 溢出内容通过裁剪来处理, 这在作者的意图是 不显示这些内容时是合理的。 这一点在CSS Overflow模块第3级中得到了进一步完善 [CSS-OVERFLOW-3]。
然而,滚动并不是展示大量内容的唯一方式, 甚至可能不是最佳方式。 毕竟,编书形式取代了卷轴, 成为大篇幅书面作品的常见格式, 因为它具有诸多优点。
本规范引入了 一种机制,允许网页指定 页面中的某个元素应通过分页来处理溢出, 而不是通过滚动。
本规范还在另一个方向上扩展了溢出概念。 而不是要求作者指定一个单一区域, 元素的内容必须流入该区域, 本规范允许作者指定多个片段, 每个片段都有其自己的尺寸和样式, 以便元素的内容可以从一个流到下一个, 使用尽可能多的片段来放置内容而不溢出。
在这两种情况下,实现都必须 在块级进展方向上打断内容。 实现必须按照 CSS Fragmentation模块的描述进行 [CSS-BREAK-3]。
溢出内容的引导:continue 属性
continue 属性允许作者 请求将无法容纳在元素中的内容 分割(在 [CSS-BREAK-3] 的意义上), 并提供剩余内容继续的替代方案。
特别是,这一属性解释了传统的分页方式, 并进一步扩展了它。
名称: | continue |
---|---|
新值: | overflow | paginate | fragments |
初始值: | auto |
适用于: | 块级容器 [CSS2], 弹性 容器 [CSS3-FLEXBOX], 以及网格容器 [CSS3-GRID-LAYOUT] |
继承: | no |
百分比: | 不适用 |
计算值: | 见下文 |
动画类型: | 离散 |
该属性及其值的命名是初步的。 它最初被提议为 "fragmentation: auto | none | break | clone | page" 在 https://lists.w3.org/Archives/Public/www-style/2015Jan/0357.html, 目前尚未广泛达成一致,哪种命名更好。
此属性旨在 通用化并取代 region-fragment。 一旦它在本规范中足够稳定,应该移除 region-fragment, 并采用该属性。
注意: continue: fragments 取代了 早期版本中 "overflow:fragments", 而 continue: paginate 取代了 "overflow: paged-x | paged-y | paged-x-controls | paged-y-controls"
- auto
-
auto 仅可能作为计算值出现,
如果元素是 CSS 区域 中的非最后一个区域,在 区域链 中。
无法容纳的内容将被推送到区域链的下一个区域。
在所有其他情况下,auto 将计算为其他值之一。
这与定义中的不同 § 5.3 溢出的分割:continue 属性, 其中指定值就是计算值。 哪种模型更好?
- overflow
- 无法容纳的内容会根据 overflow 属性溢出处理。
- paginate
-
无法容纳的内容会分页。
这将在元素内部创建分页视图,
类似于 'overflow: scroll' 创建的可滚动视图。
见 分页溢出
注意: 打印实际上就是在根元素上使用 "continue: paginate"。
- fragments
-
无法容纳的内容会使元素复制自身并继续布局。
见 碎片溢出。
给定元素或伪元素的 continue 的计算值确定如下:
- 对于具有 布局包含 的元素或伪元素(参见 [CSS-CONTAIN-1]), 如果指定值为 auto 或 fragments,则计算值为 overflow。
- 否则,如果指定值为 auto
-
否则,如果指定值为 fragments
- 对于页面 计算值为 paginate
- 否则,计算值为指定值。
- 在所有其他情况下,计算值为指定值。
如果我们引入一个可以选择多列中的列的伪元素, 我们将需要指定 auto 在它上面计算为 auto, 或者引入一个新值并让 auto 计算为那个值 (但那个值在不是列的东西上会计算成什么?)。
注意: 关于引导此属性的背景讨论,请参阅这些线程:讨论 overflow、 overflow-x、overflow-y 和 overflow-style 以及 关于分割属性的提议。
分页溢出
本节介绍并定义了 paginate 值的含义, 它是 continue 属性的一个值。
页面应能够通过 @page 规则进行样式化。嵌套页面的样式如何处理?
@media ( overflow-block: paged), ( overflow-block: optional-paged) {
:root {
continue : paginate;
}
}
传统分页(例如打印时)假定 :root 被包含在页面框内, 而不是页面框是 :root 的伪元素子元素。 我们是否可以使用类似碎片盒的方式解决这个问题? 或者通过在页面框内(重现 :root)添加一个碎片盒来处理?
[CSS3GCPM] 的最初提案和 Opera 的实现 使用了 4 个值而不是 paginate: "paged-x | paged-y | paged-x-controls | paged-y-controls"。 这个属性是否也应该包含这些值, 还是它们更适合作为独立属性处理? (例如:"pagination-layout: auto | horizontal | vertical","pagination-controls: auto | none")
能否一次显示多个页面, 而不仅仅是一次显示一个页面? 这是否可以是 "pagination-layout" 的一个值,例如: "pagination-layout: horizontal 2;"
Brad Kemper 提出了一个 将分页和碎片溢出相结合的模型, 该模型还处理显示多个页面的问题。https://www.w3.org/mid/FF1704C5-D5C1-4D6F-A99D-0DD094036685@gmail.com
当前分页溢出的实现使用了 overflow/overflow-x/overflow-y 属性, 而不是 [CSS3GCPM] 草案中提出的 overflow-style 属性, (这也符合 [CSS3-MARQUEE] 提案)、 或者本文档中描述的 continue 属性。
碎片化溢出
本节介绍并定义了 fragments 值的含义, 它是 continue 属性的一个值。
当元素的 continue 计算值为 fragments 时, 且实现本应为该元素创建一个盒子时, 实现必须为该元素创建一系列 碎片盒。 (一个设置了 continue: fragments 的元素有可能只生成一个 碎片盒。 但是,如果元素的 continue 计算值不是 fragments, 则其盒子不会是 碎片盒。) 每个 碎片盒 都是一个碎片容器, 并且任何导致该碎片容器产生碎片的溢出 都会创建另一个作为前一个的下一个兄弟节点的 碎片盒。或者它是否就像是该元素的下一个兄弟节点?需要明确这与其他盒子级别修正的确切交互方式。 另外,如果 碎片盒 也是一个多列盒子(如 [css-multicol-1] 中定义的那样,虽然它定义了 多列容器), 任何会导致创建 溢出列 的内容 [css-multicol-1] 都会 流入一个额外的碎片盒中。 然而,碎片盒本身可能会被分割 (由于它们外部的碎片上下文中的碎片化,如页面、列或其他碎片盒); 这种分割会导致同一碎片盒的多个碎片, 而不是多个碎片盒。 (这很重要,因为碎片盒可能通过其索引来进行样式设置; 这种分割会导致带有单个索引的碎片盒的多个碎片。 这种设计选择是为了 在跨页分割碎片盒时不会破坏 索引与特定内容片段的关联。)强制分页导致的分页是产生新的碎片盒,还是同一碎片盒的碎片? 我们是否应该找到比 碎片盒 更不令人困惑的术语?
如果我们想要为在另一类碎片上下文中分割的元素片段设置样式怎么办? 这些规则阻止了使用 ::nth-fragment() 来实现这一点, 尽管这个名称似乎是此类功能的最合逻辑的名称。
|
本示例中,div
中的文本
被分割为一系列 卡片。所有这些卡片 的样式相同。足够的 内容溢出一个卡片 会导致另一个卡片的创建 第二个卡片的创建就像它是
第一个卡片的下一个 兄弟节点一样。 |
|
max-lines 属性允许
作者对文章的前几行使用 较大的字体。如果没有该属性,作者
(这可能尤其困难,
如果作者不知道将 填充的确切文本、 使用的确切字体、或 用于显示字体的 确切平台) |
我们应该规定 continue: fragments 至少不适用于某些表格部分, 也许还有其他元素。 我们需要确定具体是哪些元素。
本规范需要说明创建了哪种类型的 碎片化上下文, 以便清楚地知道哪些 break-* 属性值 会在此上下文中导致分页。 我们可能希望 break-*: region 应用。
本规范需要一个处理模型 用于在布局包含碎片的情况下应用, 这些碎片的特性使用碎片的固有大小来改变可用空间量, 如 [CSS3-GRID-LAYOUT] 中所示。 该模型在 [CSS-REGIONS-1] 中已有一些工作, 并且该规范的编辑们应参与到本规范的工作中, 以确保模型的合理性。
碎片样式
::nth-fragment() 伪元素
::nth-fragment() 伪元素 是一个伪元素 用于描述由元素生成的某些 碎片盒。 伪元素的参数采用与 [SELECT] 中定义的 :nth-child() 伪类相同的语法 并且具有相同的含义, 但编号是相对于由元素生成的 碎片盒, 而不是元素的兄弟节点。
允许通过从末尾开始计数来定位碎片的选择器有意不提供。 这种选择器会干扰碎片的确定数量。
根据未来的讨论, 这个 ::nth-fragment(an+b) 语法 可能会被新的 ::fragment:nth(an+b) 语法取代。
碎片样式
这是否仅适用于 continue:fragments, 还是也适用于 continue:paginate? (如果适用, 则需要对 continue:paginate 进行更严格的属性限制。)
在没有包含 ::nth-fragment() 伪元素的规则的情况下, 每个 碎片盒 的计算样式是为生成 碎片盒 的元素计算的样式。 然而,碎片盒 的样式也受到那些选择器的规则的影响, 其选择器的 主体 包含 ::nth-fragment() 伪元素, 如果 碎片盒 的 1 基数编号匹配 该 ::nth-fragment() 伪元素, 且选择器(不包括 ::nth-fragment() 伪元素) 匹配生成碎片的元素。
在确定 碎片盒 样式时, 这些与碎片伪元素匹配的规则 与与元素匹配的规则一起层叠, 碎片伪元素增加伪类的特异性到特异性计算中。这是否也需要在层叠模块中指定?
|
在此
示例中,div 中的文本被分割 为一系列 列。作者 可能想要 文本填充两
列。但如果它碰巧 填充三列, 第三列仍会创建。 它只是没有
任何 碎片特定的样式, 因为作者 没有为其 指定任何样式。 |
使用 ::nth-fragment() 伪元素与 continue 属性进行样式设计是有效的; 如果 碎片盒 的计算值为 continue 但不是 fragments,那么该碎片盒将是最后的碎片。 然而,覆盖第一个碎片的 continue 并不会导致 碎片盒 不存在; 是否存在碎片盒完全取决于元素的 overflow 属性的计算值。
使用 ::nth-fragment() 伪元素与 content 属性进行样式设计无效; 碎片盒的 content 计算值 仍与元素的 content 计算值相同。
为 display: none 指定的 碎片盒 会导致 该索引的碎片盒不被生成。 然而,匹配 ::nth-fragment() 伪元素的后续碎片盒的索引 仍会按它被生成的方式计算。 但由于未生成,该碎片盒不会包含任何内容。
指定其他 display、 position 或 float 的值是允许的,但不能改变 内部显示类型。 (因为 continue 仅适用于块容器、弹性容器和网格容器)。需要明确指定这如何运作
为了匹配其他伪元素的模型, 伪元素位于其相应元素内部, ::nth-fragment() 伪元素中的声明覆盖 不带伪元素的规则中的声明。 这种声明的相对优先级是由正常的层叠顺序决定的(参见 [CSS2])。
在 ::nth-fragment() 伪元素中指定的样式 确实会影响碎片盒内内容的继承。 换句话说,碎片盒 内的内容必须 从碎片盒的样式(即伪元素样式)继承, 而不是直接从元素继承。 这意味着在多个碎片盒之间拆分的元素 可能会为元素的不同部分具有不同的样式。
这个继承规则 允许间接指定样式 (通过使用显式 inherit 或在不适用于 ::first-letter 的属性上使用默认继承) 而不能直接指定样式 (基于下一节中的规则)。 这是一个问题。 应该将应用于碎片内部样式的限制 也应用于从碎片继承的样式。
|
font-size 属性在碎片上指定的 值会继承到
碎片的子元素中。
这意味着继承的 属性可以在碎片中 可靠地使用, 正如本例中所示。 |
碎片内部样式
是否应仅适用于 continue:fragments,还是也应适用于 continue:paginate?
::nth-fragment() 伪元素 也可以用于样式化 碎片框内部的内容。 与::first-line 和 ::first-letter 伪元素不同, ::nth-fragment() 伪元素可以应用于选择器的其他部分: 特别是,它可以匹配目标的祖先元素。 然而,使用这种选择器的规则仅应用于 那些可以应用于 ::first-letter 伪元素的CSS属性。
更准确地说, 当规则的选择器有 ::nth-fragment() 伪元素 附加在目标以外的选择器部分时, 该规则中的声明适用于 碎片(或其伪元素),当:
- 声明应用于 ::first-letter 伪元素的属性时,
- 如果这些声明可以应用于 该碎片(或其伪元素), 假设这些 ::nth-fragment() 伪元素被移除, 并且与每个简单选择器序列关联的元素匹配,
- 对于每个移除的 ::nth-fragment() 伪元素, 碎片位于与选择器关联的元素的碎片框内部, 并且其索引与伪元素匹配。
|
附录B:scrollbar-gutter 的可能扩展
本节为非规范性内容。
本节记录了当前尝试扩展 scrollbar-gutter 属性以解决更多的使用场景。 然而,目前尚未达成共识。 此处展示的内容是为了鼓励讨论,但不建议进行非实验性的实现。
-
scrollbar-gutter: always force 应用于header/toolbar
-
scrollbar-gutter: always 应用于滚动容器
-
scrollbar-gutter: match-parent 应用于滚动容器内的每一行


名称: | scrollbar-gutter |
---|---|
新值: | auto | [ [ stable | always ] && both-edges? && force? ] || match-parent |
适用于: | 所有元素 |
对于 覆盖滚动条, 如果存在滚动条槽,其具体宽度由UA定义。 然而,它不能为0, 并且它不能根据用户与页面或滚动条的交互而改变, 即使滚动条本身发生变化, 期望其覆盖 覆盖滚动条的最大宽度, 在合理范围内予以明确。
该属性的新值含义如下:
- always
-
滚动条凹槽 总是会出现,当 overflow 是 scroll、 或 auto,无论滚动条的类型或盒子是否溢出。
scrollbar-gutter: always 可用于解决交互元素 (如较小的元素)靠近元素边缘时被弹出的覆盖滚动条遮挡的问题。 一个典型的案例是一个基本的待办事项列表,每行以文本开头,以右对齐的复选框结尾。 使用经典滚动条时一切正常,但覆盖滚动条可能会遮挡复选框,使其难以交互。
复选框与经典滚动条相邻 复选框和覆盖滚动条 覆盖滚动条通常是暂时的,在没有交互时会消失,所以虽然被遮挡的复选框仍可使用,但当滚动条出现时,它确实会妨碍交互, 这使得体验有些尴尬。作者可能会尝试通过添加一些右边距来解决这个问题,但(1)边距的大小是多少? (2)在经典滚动条的情况下不需要这种边距。scrollbar-gutter: always 解决了这个问题, 在经典滚动条的情况下效果相同,但在覆盖滚动条的情况下增加了所需的凹槽:
复选框和覆盖滚动条以及 scrollbar-gutter: always 苹果公司对添加该值持谨慎态度,因为作者可能会过度使用它, 即使没有交互元素的情况下也会在覆盖滚动条中插入凹槽,这样做会削弱覆盖滚动条节省空间的优势。已提出了一种替代解决方案:由于焦点是交互元素,或许我们可以有一个专门应用于需要避免在滚动条下的元素的属性。 当开启时,它会适当地增加元素的右或左边距,恰好将其从覆盖滚动条下推开, 但在其他情况下则保持元素不变。
另一种可能是增加一个切换选项, 使元素同时增加其行尾和行首边距,或都不增加,而不仅仅是一侧。 这通常对具有可见边框或背景的滚动区域的块级后代元素有用: 为避免与覆盖滚动条发生冲突在一侧增加空间,会使当滚动条消失时元素看起来不居中。 增加两侧的边距可以避免这种情况。
另一种可能性是可以选择增加边距以保护元素,或者增加内边距以保护元素的内容。
语法可能类似于
scrollbar-avoid: none | [self | content] && both-edges?
。一个有趣的考虑是,这可能会减轻 scrollbar-gutter: match-parent 的需求, 因为看起来可以通过在父元素上使用 scrollbar-gutter: stable 或 scrollbar-gutter: always, 而在选中的子元素上使用 scrollbar-gutter: match-parent 来解决的问题, 可以通过将父元素设置为 scrollbar-gutter: auto, 并在相关的子元素上使用
scrollbar-avoid: self
或scrollbar-avoid: content
来解决。 - force
-
当 force 关键字存在时,
stable 和 always
生效,
当 overflow 为 visible、 或 clip,以及 auto 或 scroll。
这不会导致显示滚动条,只会显示 滚动条凹槽。
此值允许作者保留与滚动条相邻元素边缘相同数量的空间, 以便它们的内容可以在视觉上对齐。 同样的效果可以通过为经典滚动条添加内边距而为覆盖滚动条不添加内边距来实现, 但是没有这种方式,作者无法可靠地知道是否应该添加内边距,如果是,应该添加多少。
一个具体的例子可以在Gmail的UI中看到(在撰写本文时), 它试图(但并不总是成功)将邮件列表上方工具栏中的控件与邮件列表中的控件对齐。 以下是两个截图,一个是打开经典滚动条时(在操作系统级别),Gmail正确猜出了应该为列表上方的工具栏添加多少内边距, 另一个是打开覆盖滚动条时,Gmail错误地添加了内边距,导致对齐错乱 (用橙色虚线手动添加以突出讨论点)。
带有经典滚动条的Gmail UI 带有覆盖滚动条的Gmail UI 通过使用 scrollbar-gutter: stable force 而不是内边距来创建此间距, 可以在两种情况下保持图标对齐,并且在滚动条尺寸不典型的系统上也可以保持对齐。
正是由于此值, 该属性已被扩展为适用于所有元素,而不仅仅是 滚动容器, 以便它可以适用于示例中所示的 overflow: visible 元素。 这可能会带来实现困难,因为用户代理不能仅依赖现有代码来放置凹槽, 因为他们可能需要在之前无法放置凹槽的元素上进行操作。 将其限制为所有适用 overflow 的元素可能对用例不会产生负面影响, 并且可以简化实现;然而,即使这样,可能仍然比仅限于 滚动容器 的限制更困难。
除了上面提到的实现挑战外, 还不清楚该值是否能如预期那样可靠地解决问题。 由于滚动条及其凹槽的大小和位置由用户代理定义, 它们可能因不同的元素而有所不同。 由于滚动条的外观和位置由用户代理决定, 影响它们的属性列表可能没有限制。 很可能通过设置 direction(通过设置 HTML 的 dir 属性) 或 scrollbar-width 等属性, 可以为用户代理提供足够的上下文,以了解它将在该元素上创建的滚动条的样式, 从而在正确的位置创建大小相同的凹槽,但这不能得到保证。
在规范的早期迭代中, 这是唯一可以实现示例中效果的方式。 然而,自那时以来,scrollbar-gutter: stable 已被应用于 overflow: hidden 元素。 虽然在这种情况下应用 overflow: hidden 可能会产生其他不希望的效果, 但结合 scrollbar-gutter: stable 和 overflow: hidden 的组合确实像 scrollbar-gutter: stable force 一样增加了间距, 可能被证明是一个足够的解决方法,特别是在考虑到上述其他问题时。
- match-parent
-
在父级具有 块级 盒子的情况下,该盒子有 滚动条凹槽(或在两边有凹槽),
这会使该盒子在与其父级相同的侧边拥有相同宽度的凹槽。
此外,
该凹槽会与父级盒子的凹槽重叠。
如果带有 scrollbar-gutter: match-parent 的盒子在期待有凹槽的边有非零的 边框或边距, 那么该盒子的凹槽大小为
parent.gutter - child.border - child.margin
, 并且凹槽+边框+边距与父级的凹槽折叠。如果带有 scrollbar-gutter: match-parent 的盒子本身是一个 滚动容器, 那么根据滚动条的类型、 overflow 属性, 以及 scrollbar-gutter 属性的其他值, 它可能需要为其自己的滚动条增加额外的凹槽。 这是在为 match-parent 值添加的凹槽的基础上增加的, 并不会与父级的凹槽折叠。
由于 match-parent,一个带有子级背景的滚动容器侵入凹槽。 带有经典滚动条的滚动容器中的 match-parent 盒子, overflow: auto, 以及 scrollbar-gutter: stable 一个滚动盒子,内部有另一个带有 match-parent 的滚动容器 一个带有 match-parent 的滚动盒子,内部有另一个带有双向文本的滚动容器。 一个带有 scrollbar-gutter: match-parent stable 的滚动盒子,内部有另一个双向滚动容器。
overflow | scrollbar-gutter | 经典滚动条 | 覆盖滚动条 (无论是否溢出) | |
---|---|---|---|---|
溢出时 | 不溢出时 | |||
scroll | auto | 是 | 是 | |
stable | 是 | 是 | ||
always | 是 | 是 | 是 | |
auto | auto | 是 | ||
stable | 是 | 是 | ||
always | 是 | 是 | 是 | |
auto | ||||
stable | 是 | 是 | ||
always | 是 | 是 | 是 | |
visible、clip | auto | |||
stable | 如果 force | 如果 force | ||
always | 如果 force | 如果 force | 如果 force |
附录 C: 隐私考虑
本规范未引入新的隐私考虑事项。
附录 D: 安全考虑
本规范未引入新的安全考虑事项。
变更
最近的变更
自 2017年6月工作草案 以来的重要变更包括:
- 将 text-overflow 的定义从 [CSS-UI-4] 移入。
- 将 scrollbar-gutter 的核心定义移至 [CSS-OVERFLOW-3] (规范取消差异后会将其复制回来),并将探索性的 scrollbar-gutter 扩展想法移至附录。
- 定义了 overflow 和 overflow-clip-margin 的扩展,使其适用于 替换元素。 具体如何实现这一点仍在 讨论中。 (问题7144)
- 为 overflow-clip-margin 定义了 简写形式。 (问题7245)
自第3级以来的变更
致谢
特别感谢以下人员的反馈: Rossen Atanassov, Bert Bos, Tantek Çelik, John Daggett, fantasai, Daniel Glazman, Vincent Hardy, Håkon Wium Lie, Peter Linss, Robert O’Callahan, Florian Rivoal, Alan Stearns, Steve Zilles, 以及所有 www-style 社区的成员。