CSS 多栏布局模块 第 2 级

W3C 首次公开工作草案

关于本文件的更多信息
本版本:
https://www.w3.org/TR/2024/WD-css-multicol-2-20241219/
最新发布版本:
https://www.w3.org/TR/css-multicol-2/
编辑草案:
https://drafts.csswg.org/css-multicol-2/
历史记录:
https://www.w3.org/standards/history/css-multicol-2/
反馈:
CSSWG 问题仓库
规范内问题列表
编辑者:
Florian Rivoal代表 Bloomberg
Google
前任编辑:
Opera Software
对本规范建议修改:
GitHub 编辑器
测试套件:
https://wpt.fyi/results/css/css-multicol/

摘要

本规范描述了 CSS 中的多栏布局,CSS 是用于 Web 的样式表语言。使用本规范中描述的功能,内容可以自动流入多个栏,并在栏之间设置间隙和分隔线。

CSS 是一种用于描述结构化文档(如 HTML 和 XML)在屏幕、纸张等上的渲染方式的语言。

本文档状态

本节描述了本文档在发布时的状态。 当前 W3C 发布物列表及本技术报告的最新修订版, 可在 W3C 技术报告索引 https://www.w3.org/TR/ 查阅。

本文档由 CSS 工作组首次公开工作草案 的形式,并采用 推荐标准流程 发布。 作为首次公开工作草案发布, 并不意味着 W3C 及其成员的认可。

本文档为草案文档, 可能随时被更新、替换或废弃。 除作为进展中工作外,不应引用本文件。

请通过 在 GitHub 提交 issue(推荐方式)反馈, 标题中请包含规范代码“css-multicol”,例如: “[css-multicol] …评论摘要…”。 所有问题和评论都会被 存档。 或者,也可以发送反馈到(有存档)的公共邮件列表 www-style@w3.org

本文档受 2023年11月3日 W3C 流程文件 管辖。

本文档由遵循 W3C 专利政策 的小组制作。 W3C 维持着与本小组交付物相关的专利披露公开列表; 该页面还包含专利披露的说明。 若个人实际知晓某专利并认为其包含必要声明, 必须按 W3C 专利政策第6节 披露相关信息。

1. 引言

(本节为非规范性内容。)

本模块描述了 CSS 中的多栏布局。 使用本文档描述的功能, 样式表可以声明将某个元素的内容以多栏方式排布。

CSS 中的其他布局方式, 当应用于父元素时, 会改变其直接子元素的显示属性。 例如,若创建了三栏网格布局, 网格容器的直接子元素会变为网格项(grid items),并被放入列轨道中, 每个单元格一个元素,必要时可增加新行。

多栏容器的子元素依然处于正常流中, 只不过该流被安排到若干栏中。 这些栏的内联尺寸是灵活的, 会根据可用空间变化而调整显示的栏数或栏的宽度。

多栏布局在 CSS 中很容易描述。 下面是一个简单的例子:

body { column-width: 12em }

在此示例中,body 元素被设置为栏宽最小为 12em。具体栏数取决于可用空间。

也可以在样式表中显式设置栏数:

body { column-count: 2 }

此时,栏数是固定的,栏宽会根据可用宽度变化。

可以使用简写 columns 属性在一条声明中设置其中一个或两个属性。

在以下示例中,分别设置了栏数、栏宽,以及同时设置栏数与栏宽:
body { columns: 2 }
body { columns: 12em }
body { columns: 2 12em }

本模块还引入了一组用于描述栏间间隙和分隔线的属性。

body {
  column-gap: 1em;
  column-rule: thin solid black;
}

上例的第一条声明设置了两栏之间的间隙为 1em。 栏间隙类似于内边距区域。 在间隙中间会有一条分隔线, 其样式由 column-rule 属性描述。

column-rule 属性的取值类似于 CSS border 属性。 就像 bordercolumn-rule 也是一个简写属性。

在此示例中,上述简写的 column-rule 声明被展开为:
body {
  column-gap: 1em;
  column-rule-width: thin;
  column-rule-style: solid;
  column-rule-color: black;
}

column-fillcolumn-span 属性 让样式表在多栏布局中拥有更丰富的视觉表现力。

在此示例中,栏被设置为平衡,即长度大致相同。 同时,h2 元素被设置为跨越全部栏。
div { column-fill: balance }
h2 { column-span: all }

本规范引入了十个新属性, 上述示例全部用到了这些属性。

如果所有栏属性都为初始值, 元素布局将与仅有一栏的多栏布局完全一致。

下图的多栏容器示例中展示了栏间隙(斜线阴影)和栏分隔线,以及带有内边距(交叉阴影)的多栏容器渲染效果。 阴影区域仅为示意。 实际实现时,这些区域由背景决定。 第二张图片展示了带有栏分隔线的多栏容器的渲染。
a diagram showing the various parts of multi-column layout key to the conventions used to display invisible parts of diagram
高亮显示多栏布局中不可见的 column-span 和多栏容器内的 padding 部分。
a diagram showing the various parts of multi-column layout
与第一张图片相同的布局,展示了实现时的实际渲染效果。

1.1. 值定义

本规范遵循 CSS 属性定义约定 [CSS21],并采用 值定义语法 [CSS-VALUES-3]。 本规范未定义的值类型,在 CSS Values & Units [CSS-VALUES-3] 中定义。 与其他 CSS 模块组合时,这些值类型定义可能会扩展。

除了在各自定义中列出的属性专用值外, 本规范定义的所有属性还接受 CSS 通用关键字 作为属性值。 为了可读性,这些值未在各属性定义中重复列出。

2. 模块交互

本文档定义了早期规范中未出现的新特性。 最终版本发布后,将替代以下内容:

3. 多栏模型

当元素的 column-widthcolumn-count 属性不是 auto 时,该元素会建立一个多栏容器(简称 multicol container), 进而作为多栏布局的容器。

在传统 CSS 盒模型中, 元素内容流入对应元素的内容盒中。 多栏布局引入了一种由分片上下文组成的模型,该上下文由匿名分片容器构成,称为栏盒(简称 columns)。 这些栏盒建立独立的块格式化上下文,多栏容器的内容流入其中, 并作为其非定位子项的包含块

在此示例中,图片的宽度通过如下规则设置:
img {
  display: block;
  width: 100%;
}

由于栏盒会创建新的块格式化上下文width 会相对于栏盒计算, 因此图片不会溢出栏盒:

an image contained inside a column box
图片受其所在栏盒约束。
由于栏盒创建了新的块格式化上下文,多栏容器第一个子元素设置的上外边距不会与多栏容器的外边距折叠。
The first paragraph has a 'margin-top' of ''1em'', which appears before the text.
多栏容器中首段上方的 1em 外边距未折叠。

出现在多栏布局内的浮动元素,其定位以其所在栏盒为准。

在此示例中,CSS 片段描述了图片的表现:
img {
  display: block;
  float: right;
}

在 HTML 中,图片出现在“the leg of a chicken”句子之后。

an image floated and contained inside a column box
图片在其所在栏盒内浮动。

栏盒块轴方向上溢出的内容会分片并继续流到下一个 栏盒

注意: 栏盒是匿名盒, 不会成为包含块,不作为绝对定位盒的包含块。 position 属性建立这些盒的包含块, 作用于多栏容器(即主盒)。

在此示例中,多栏容器设置了 position: relative,成为包含块。 图片是 多栏容器 的直接子元素,并设置了 position: absolute。 其定位参考的是 多栏容器,而不是栏盒
.container {
  position: relative;
  column-count: 3;
}
img {
  position: absolute;
  top: 20px;
  left: 40px;
}
The absolutely positioned image is positioned by reference to the [=multi-column container=] not the [=column box=].
该示例演示了绝对定位图片是以多栏容器为参考而非栏盒。

多栏容器的脱离流后代会影响栏的平衡以及 多栏容器 的块尺寸。

栏盒的排列顺序依赖于多栏容器的内联基方向,并被组织为多栏行栏宽指栏盒在内联方向的长度。 栏高指栏盒在块方向的长度。 同一行内所有栏盒宽度一致,高度一致。

注意: 在使用垂直书写模式的文本中, 块方向是水平方向。 垂直书写模式下,栏水平排列, 块流方向可为从右到左或从左到右。 column-width 属性因此指栏的内联尺寸, 而不是物理上的水平宽度。

The first image shows horizontal text with a LTR inline direction. The second shows vertical text with blocks flowing right to left. The third shows vertical text with blocks flowing left to right.
该图展示栏在不同书写模式下的排列方式。
从左至右依次为:horizontal-tb、vertical-rl、vertical-lr。

在多栏容器的每个多栏行内, 相邻栏盒之间用一个栏间隙分隔, 其中可包含一个栏分隔线。 同一多栏容器内所有栏隙相等, 所有栏分隔线(如有)也相等; 栏分隔线只出现在两侧均有内容的栏之间。

最简单情况下,多栏容器仅含一行栏,且每栏高度等于多栏容器内容盒的实际高度。 但分片跨栏元素可将多栏容器内容分为多行多栏行

若多栏容器被分页,每栏的高度受页面约束,内容会在下一页新行栏盒中继续;栏盒不会跨页分割。

跨栏元素 分割多栏容器时也会出现类似效果:跨栏元素前的各栏会被平衡并缩短以适应内容,跨栏元素后的内容流入一组新的栏盒。

a diagram showing a spanning element causing the shortened columns above the element with text continuing in new columns below
展示跨栏元素如何分割多栏容器。

因此,多栏容器是一个常规的块容器,会建立新的独立格式化上下文,其内容由一系列多栏行和跨栏元素组成。 每个 多栏行 作为一个块级盒,为其栏盒建立多栏格式化上下文; 每个跨栏元素作为 块级盒,根据其 display 属性建立相应类型的独立格式化上下文

允许嵌套多栏容器, 但实现上可能有特定限制。

注意: 不能对栏盒设置属性/取值。 例如无法为某个特定栏盒设置背景,栏盒也没有内边距、外边距或边框的概念。 未来的规范可能会增加更多功能。 例如支持不同宽度、不同背景的栏。

注意: 栏高大于视口的多栏容器可能带来可访问性问题。 详见可访问性注意事项

4. 栏数与栏宽

确定栏数和栏宽是进行多栏内容布局的基础。 以下属性用于设置栏的数量和宽度:

第三个属性 columns, 是一个简写属性,用于同时设置 column-widthcolumn-count

其他因素,如显式的栏断点、内容和高度约束,也可能影响实际的栏数和栏宽。

4.1. 栏的内联尺寸:column-width 属性

名称: column-width
取值: auto | <length [0,∞]>
初始值: auto
适用于: 块容器,不包括 表包装盒
是否继承:
百分比: 不适用
计算值: 关键字 auto 或绝对长度
规范顺序: 按语法
动画类型: 按计算值类型

此属性描述多栏容器中栏的宽度。

auto
表示栏宽由其他属性决定 (如 column-count 不是 auto 时)。
<length [0,∞]>
描述理想的栏宽。 实际栏宽可能会变宽(以填满可用空间), 也可能变窄(仅当可用空间小于设定栏宽时)。 不允许负值。 使用值会被限制为最小 1px
例如,考虑如下样式表:
div {
  width: 100px;
  column-width: 45px;
  column-gap: 0;
  column-rule: none;
}

100px 宽的元素内,可以容纳两个 45px 宽的栏。 为了填满可用空间, 实际栏宽会被增加为 50px

还有如下样式表:
div {
  width: 40px;
  column-width: 45px;
  column-gap: 0;
  column-rule: none;
}

可用空间小于指定的栏宽, 因此实际栏宽会被缩小。

为确保 column-width 可用于竖排文本, 栏宽指栏内部行盒的长度。

注意: 设置 column-width 具有一定灵活性的原因是为了实现可适配多种屏幕的可扩展设计。 若要设置精确栏宽, 还必须同时指定栏间隙和多栏容器宽度(假设为横排文本)。

4.2. 栏数:column-count 属性

名称: column-count
取值: auto | <integer [1,∞]>
初始值: auto
适用于: 块容器,不包括 表包装盒
是否继承:
百分比: 不适用
计算值: 指定值
规范顺序: 按语法
动画类型: 按计算值

此属性描述多栏容器的栏数。

auto
表示栏数由其他属性决定 (如 column-width 不是 auto 时)。
<integer [1,∞]>
描述内容将被流入的理想栏数。 取值必须大于 0。 若 column-widthcolumn-count 都不是 auto, 则整数值表示最大栏数。
示例:
body { column-count: 3 }

4.3. column-widthcolumn-count 简写:columns 属性

名称: columns
取值: <'column-width'> || <'column-count'>
初始值: 见各自属性
适用于: 见各自属性
是否继承: 见各自属性
百分比: 见各自属性
计算值: 见各自属性
动画类型: 见各自属性
规范顺序: 按语法

这是用于同时设置 column-widthcolumn-count 的简写属性。 省略的值会被设置为其初始值。

以下是一些使用 columns 属性的合法声明:
columns: 12em;      /* column-width: 12em; column-count: auto */
columns: auto 12em; /* column-width: 12em; column-count: auto */
columns: 2;         /* column-width: auto; column-count: 2 */
columns: 2 auto;    /* column-width: auto; column-count: 2 */
columns: auto;      /* column-width: auto; column-count: auto */
columns: auto auto; /* column-width: auto; column-count: auto */

4.4. 伪算法

下面的伪算法用于计算 column-count(N)和 column-width(W)的使用值。伪算法中还有一个变量:U 表示多栏容器的使用宽度。

注意: 多栏容器的使用宽度 U 可能依赖于元素内容, 此时也取决于 column-countcolumn-width 的计算值。 本规范未定义 U 的计算方式, 另一份规范(可能为基本盒模型 [CSS3BOX] 或 盒尺寸模块 [CSS3-SIZING])将定义此内容。

floor(X) 函数返回不大于 X 的最大整数 Y。

(01)  if ((column-width = auto) and (column-count = auto)) then
(02)      exit; /* not a multicol container */
(03)  if column-width = auto then
(04)      N := column-count
(05)  else if column-count = auto then
(06)      N := max(1,
(07)        floor((U + column-gap)/(column-width + column-gap)))
(08)  else
(09)      N := min(column-count, max(1,
(10)        floor((U + column-gap)/(column-width + column-gap))))

并且:

(11)  W := max(0, ((U + column-gap)/N - column-gap))

为确定自动重复栏数, UA 必须将栏尺寸向下取整到 UA 指定的值以避免除零错误。 建议此取整为 1px 或更小。

在分片上下文中,如 分页媒体, 用户代理可针对每个分片分别执行该计算。

column-count 的使用值计算时不考虑显式栏断点或栏高约束, 而实际值会考虑这些因素。

在此示例中,由于有显式栏断点,实际栏数大于使用栏数:
div {
  width: 40em;
  columns: 20em;
  column-gap: 0;
}

p {
  break-after: column;
}
<div>
  <p>one
  <p>two
  <p>three
</div>
Two columns drawn inside the container, one outside
计算栏数为 auto,使用栏数为 2,实际栏数为 3。
实际栏数也可能小于使用栏数。 如下示例:
div {
  width: 80em;
  height: 10em;
  columns: 20em;
  column-gap: 0;
  column-fill: auto;
}
<div>foo</div>

计算栏数为 auto, 使用栏数为 4, 实际栏数为 1。

4.5. 堆叠上下文

多列容器中的所有列框都处于同一个堆叠上下文中,其内容的绘制顺序如 CSS 2.1 所规定。列框不会建立新的堆叠上下文。

4.6. 列样式:::column 伪元素

::column 伪元素 表示多列容器中的单独列。 它只存在于多列容器上。

一个多列容器拥有与其列数相同数量的::column伪元素。 它们不能被单独选中; 任何应用于多列容器 ::column 伪元素的样式 都会应用到该元素上的所有列伪元素上。 每个 ::column 的尺寸和位置 与其对应的列一致: 在行内轴上与该列可用空间一致, 在块轴上与容器的内容框一致。 (它不会覆盖列间的间隙/分隔线。)

::column 伪元素被视为其多列容器的子元素, 但没有任何内容。 它们不会包裹列的内容, 只是填充相同的空间。

::column 伪元素只接受非常有限的属性:

此外,::column 伪元素可以拥有自己的 ::scroll-marker 伪元素, 形式为 ::column::scroll-marker。 (其他伪元素不会出现在::column上。) 这样的 ::scroll-marker 伪元素 继承自 ::column 伪元素的起始元素, 而不是 ::column 本身。

注: 适用于 ::column 的属性和伪元素列表 未来可能会扩展, 随着我们开发更多能够关心列位置而不关心内容的新特性。

5. 列间隙与分隔线

列间隙和分隔线被放置在同一个多列容器的各列之间。 列间隙和分隔线的长度等于列的高度。 列间隙会占用空间。 也就是说,列间隙会将相邻列的内容分开 (在同一个多列容器内)。

列分隔线绘制在列间隙的中间, 两端在多列容器的相对内容边缘。 列分隔线不占用空间。 也就是说,列分隔线的存在或宽度不会影响其他内容的布局。 如果 列分隔线 宽度大于间隙, 相邻的列框会覆盖分隔线, 并且分隔线可能会超出多列容器的盒子。 列分隔线绘制在多列容器的边框之上。 对于可滚动的多列容器, 注意虽然多列容器的边框和背景不会跟随滚动, 但分隔线需要与列一起滚动。 列分隔线只会绘制在两个都有内容的列之间。

5.1. 列间隙:column-gap 属性

column-gap 属性在 [CSS3-ALIGN] 中定义。

多列排版上下文中,normal 用作 column-gap 属性的有效值为 1em。 这样可以确保使用初始值时各列内容可读。 如果列之间存在分隔线, 它会出现在间隙的中间。

5.2. 列分隔线颜色:column-rule-color 属性

名称: column-rule-color
值: <color>
初始值: currentcolor
适用对象: 多列容器
是否继承:
百分比: N/A
计算值: 计算后的颜色
规范顺序: 按语法
动画类型: 按计算值类型
<color>
指定列分隔线的颜色。

5.3. 列分隔线样式:column-rule-style 属性

名称: column-rule-style
值: <line-style>
初始值: none
适用对象: 多列容器
是否继承:
百分比: N/A
计算值: 指定的关键字
规范顺序: 按语法
动画类型: 离散

column-rule-style 属性设置元素各列之间分隔线的样式。 <line-style> 的取值方式与边框折叠模型一致。

nonehidden 值会强制 column-rule-width 的计算值为 0

5.4. 列分隔线宽度:column-rule-width 属性

名称: column-rule-width
值: <line-width>
初始值: medium
适用对象: 多列容器
是否继承:
百分比: N/A
计算值: 绝对长度, 按边框宽度对齐;如果列分隔线样式为 nonehidden 时为 0
规范顺序: 按语法
动画类型: 按计算值类型

该属性设置列间分隔线的宽度。 不允许为负值。

5.5. 列分隔线速记属性:column-rule 属性

名称: column-rule
值: <'column-rule-width'> || <'column-rule-style'> || <'column-rule-color'>
初始值: 见各独立属性
适用对象: 见各独立属性
是否继承: 见各独立属性
百分比: 见各独立属性
计算值: 见各独立属性
动画类型: 见各独立属性
规范顺序: 按语法

该属性用于在样式表中同时设置 column-rule-widthcolumn-rule-stylecolumn-rule-color。 省略的值将被设为各自的初始值。

在此示例中,列分隔线列间隙宽度相同。 因此,它们将完全占据相同的空间。
body {
  column-gap: 35px;
  column-rule-width: 35px;
  column-rule-style: solid;
  column-rule-color: black;
}
分隔线完全覆盖了间隙区域。
列分隔线和列间隙占据了相同的空间。

6. 列断开

当内容以多列布局时, 用户代理必须决定列断点的位置。 将内容分割为多列的问题与分页类似, 详见 CSS 2.1 第 13.3.3 节 [CSS21]

引入了三个新属性,以便可在与分页断点相同的属性中描述列断点:break-beforebreak-afterbreak-inside

6.1. 控制分片:break-beforebreak-afterbreak-inside 属性

break-beforebreak-afterbreak-inside[CSS3-BREAK]中定义。

7. 跨列

column-span 属性可以让一个元素跨越多列显示。 本规范为上一等级的可选值中增加了 <integer>

7.1. column-span

名称: column-span
值: none | <integer [1,∞]> | all | auto
初始值: none
适用对象: 流内的块级元素
是否继承:
百分比: N/A
计算值: 指定值
规范顺序: 按语法
动画类型: 离散

该属性描述元素跨越多少列。可选值有:

none
元素不会跨越多列。
all
元素会强制发生列断点,并被 脱离文档流, 跨越其最近的多列祖先 (同一块格式化上下文内)的所有列。 正常流中出现在该元素之前的内容 会在该元素出现之前自动在所有列中均衡分布, 后续内容会在该元素之后流入新的 多列行。 该元素会建立一个独立格式化上下文

注: 元素是否建立新的格式化上下文,与它是否为多列的后代无关。 当 column-span 设置为 all 时,总是如此。 这样有助于在后续移除多列或媒体查询关闭多列时保持设计的健壮性。

<integer [1,∞]>
元素跨越指定数量的列。 值必须大于 0。 如果指定的整数等于或大于多列元素的列数, 跨越的列数效果等同于指定 column-span: all
此定义尚不充分。
  • column-span: 1 应等同 column-span: none, 还是应该创建一个跨列元素(spanner,BFC)?
  • 到底跨了哪几列?
  • 这对高度计算和 column-fill 有什么影响?
auto
元素跨越多少列依赖于其最小内容外部尺寸多列容器的行内方向上的值。 如果比 column-width 的用值还小, 则等同于 column-span: none。 否则,跨越的列数为最小正整数 n,满足 n × column-width + (n - 1) × column-gap 大于其 最小内容 外部尺寸。 如果大于容器列数, 则效果等同于 column-span: all

column-span: 1 不等同于 column-span: none, 那么当元素本身很小时应表现为 column-span: 1 还是 column-span: none

跨越多列的元素被称为 多列跨越元素, 其创建的盒子称为 跨列盒(spanner)

跨列盒包含块多列容器 本身。 因此,如果跨列盒本身未建立 包含块用于其内部的绝对定位盒, 那么它们的 包含块链会直接跳到 多列容器(跳过 跨列盒多列容器之间的任何祖先)。

尽管跨列盒被脱离文档流, 这不会影响跨列元素的绘制顺序 [CSS21]

在该示例中,一个 h2 元素被添加到示例文档的第六句话之后 (即“the leg of a”之后)。 应用的样式如下:
h2 { column-span: all; background: silver }

column-span 设为 all 后, h2 元素之前的所有内容 都会显示在 h2 元素之上。

An element spans all three columns
h2 元素设置 column-span: all 后跨越了所有列。

注意,由于跨列盒会断开多列行, 也会中断任何列分隔线 (只会画在 多列行的各列之间)。

只要属于同一个格式化上下文, 并且跨列元素和多列容器之间没有建立固定定位后代的包含块的东西, 跨列元素可以低于第一层后代出现。

在该例中,column-span: all 的元素位于 transform: rotate(90deg) 的元素内部。 transform 会为固定定位后代建立包含块, 因此不会创建跨列盒。
<article>
  <section>
    <div class="spanner">Attempted spanner</div>
  </section>
</article>
article {
  columns: 2;
}

section {
  transform: rotate(90deg);
}

.spanner {
  column-span: all;
  background: silver;
}

如果跨列盒前的片段为空,则不会有特殊情况; 顶部的 margin/border/padding 会出现在跨列元素上方,作为一个空的片段

在该示例中,多列容器article 元素。 这个父元素内有一个段落和一个 section 元素。 section 内有一个 h2 标题设置为 all,它跨越了所有三列, 而 section 本身仍在列内。

h2 是 section 的第一个子元素。 这意味着 section 的 margin、border(红色显示)和 padding 会作为空片段出现在跨列 h2 之前。

<article>
  <p>...</p>
  <section>
    <h2>An h2 element</h2>
    <p>...</p>
  </section>
</article>
section {
  border: 2px solid red;
  margin-top: 65px;
  padding-top: 20px;
}

h2 {
  column-span: all;
  background: silver
}
An element spans all three columns, the red border around the section breaks before the spanner.
h2 元素设置为 column-span: all, section 有红色边框和顶部内外边距

跨列元素占用空间比普通元素更多。 当空间有限时,可能无法为其留出足够空间。 此时,用户代理可以将该元素视为本属性值为 none

在该示例中,h2 元素出现在内容较后的位置, 多列容器的高度受限。 因此,h2 出现在溢出部分,无法跨列显示。 结果,该元素表现得就像指定了 column-span: none
The h2 element is in an overflow column
h2 元素在溢出列中,表现为 column-span: none
本例与上例类似, 只是 H2 元素自然出现在最后一列。 依然没有足够空间实现跨列。
The h2 element is in the final column
h2 元素在最后一列,表现为 column-span: none
在分页等分片环境下,跨列元素会在所有分片中被遵循。 本例在 分页媒体环境下, 前 3 段落后都强制列断开。 第四段后出现一个跨列 H2 元素。
Three columns with two lines of text each
这会出现在第一页
A spanning element across the three columns, text above and below.
这会出现在第二页

跨列盒为块级盒, 因此两个相邻跨列盒的外边距会合并。 仅被绝对定位项分隔的两个跨列盒的外边距也会合并, 因为绝对定位项不会创建列框。 由于列框会建立新的块格式化上下文, 列框内部元素的外边距不会和跨列盒的外边距合并。

跨列盒会建立新的格式化上下文,但它们的外边距依然会受周围影响。 该例中,两个跨列盒自然出现在页面顶部。 第一个跨列盒顶部外边距因与未强制断开的内容相邻而被截断。 两个跨列盒之间的外边距会合并, 但第二个跨列盒的底部外边距不会与后续元素的顶部外边距合并。
h2 {
  margin: 16px 0;
  column-span: all;
  background: silver
}
p { margin-top: 16px }
Two spanning elements after a page break
两个跨列元素之间的外边距会合并,但跨列盒底部外边距不会和下一个元素的顶部外边距合并。

8. 填充列

填充列有两种策略: 可以让各列均衡,或者不均衡。 如果各列均衡,用户代理应尽量使列高变化最小, 同时要遵循强制断点、widowsorphans 及其它可能影响列高的属性。 如果不均衡,则按顺序填充各列; 有些列可能只填了一部分,甚至完全为空。

8.1. 列均衡:column-fill 属性

名称: column-fill
值: auto | balance | balance-all
初始值: balance
适用对象: 多列容器
是否继承:
百分比: N/A
计算值: 指定关键字
规范顺序: 按语法
动画类型: 离散

该属性指定 在多列行不是紧接着一个跨列盒的内容是否在各列间均衡分布。

可选值为:

balance
内容尽量在各列均衡分布。 在分片环境下,仅最后一个分片均衡。
balance-all
内容尽量在各列均衡分布。 在分片环境下,所有分片均均衡。
auto
顺序填充各列

在连续环境中,当存在溢出列时该属性无效。

本例中,一个 article 只有一小段短文本三行。 由于列均衡,这三行会分别显示在三列中。
article {
  width: 60em;
  height: auto;
  columns: 4;
  column-fill: balance;
}
Four columns, the first three have content.
三行文本因列均衡分别显示在三列中。
本例关闭了列均衡,且 article 有固定高度:
article {
  width: 60em;
  height: 4em;
  columns: 4;
  column-fill: auto;
}

结果,所有内容都填充在第一列:

Four columns, the first one has content.
未均衡时,所有文本显示在一列中。
本例 article 有两段文本: 先是一段长文本, 然后一段短文本。 应用样式如下:
article {
  width: 60em;
  height: auto;
  columns: 4;
  column-fill: balance;
}

p {
  break-after: column;
}

最短列高为五行文本。 列高确定后,内容顺序填充各列。 结果第三列与前两列等高,最后一列远远较短。

Four columns, all have content.
列高确定后,内容顺序填充各列。
article {
  width: 60em;
  height: auto;
  columns: 4;
  column-fill: balance;
}

本例,article 以一个不可断开的 figure 开头,这决定了列高。 随后内容被顺序填充到剩余列:

Column one contains an image, two and three have content.
列高由 figure 决定。

9. 溢出

9.1. 多列容器内部的溢出

除非会导致列断开,否则超出列框的内容会直接溢出显示,并不会被列框裁剪。

注: 关于列断开见§ 6 列断开, 关于是否被裁剪到多列容器的内容框见§ 9.2 多列容器外部的分页与溢出

本例中图片宽度大于列宽:
An imagine in the first column has visible overflow
内容会直接溢出列框,不会被裁剪。

9.2. 多列容器外部的分页与溢出

超出多列容器边缘的内容和列分隔线会根据overflow属性被裁剪。

由于以下原因,多列容器可能会拥有超出空间的列数:

在连续环境中,出现在多列容器外的列被称为溢出列。 溢出列可能会影响多列容器的高度。

本例中,多列容器高度被限制为最大高度。 并且样式表指定溢出内容可见:
div {
  max-height: 5em;
  overflow: visible;
}

因此,列数会增加。

Four columns, one outside the multicol container
行内方向生成了溢出列。

在连续环境中,溢出列可能影响多列容器的高度。 本例溢出列包含四行文本。 多列容器高度会调整以容纳该列。

Four columns, overflow column is taller than the first three
最后一列为溢出列,高度大于其他列,容器高度也随之增加。
在分片环境中,溢出内容会进入后续分片的列中。 假设内容与例31相同,页面框只能容纳5行格式化文本, 第一页效果如下:
Three columns
前三个段落显示在第一页。

假设列均衡,第二页效果如下:

Three columns
溢出列被移到第二页。
本例段落后显式生成列断开:
p {
  break-after: column;
}

因此,列数增加,额外的列在行内方向生成:

Four columns, one outside the multicol container
行内方向生成了溢出列。
分页媒体中, 多余的列会显示在下一页。 与上例代码相同,最后一个段落显示在第二页。 第一页效果如下:
Three columns
前三个段落显示在第一页。

第二页效果如下:

Three columns
溢出列被移到第二页。

由于列均衡,最后一个段落会分布在三列中。

附录 B. 变更记录

本附录为说明性内容

2024年5月16日的 CSS-MULTICOL-1 候选推荐(CR)的变更

隐私注意事项

多列布局不会引入新的隐私泄露。

安全注意事项

多列布局不会引入新的安全问题。

可访问性注意事项

设置容器高度和行长可能会给视觉或认知障碍人士带来挑战。 参见 WCAG 成功标准 1.4.10 重排WCAG 1.4.8 可视化呈现 以了解用户需求。

致谢

本文档基于 Håkon Wium Lie 在 [CSS3-MULTICOL] 中的工作, 并参考了多个早期方案及评论。 贡献者包括:

Alex Mogilevsky、 Andy Clarke、 Anton Prowse、 Bert Bos、 Björn Höhrmann、 Cédric Savarese、 Chris Lilley、 Chris Wilson、 Daniel Glazman、 Dave Raggett、 David Hyatt、 David Singer、 David Woolley、 Elika Etemad、 Giovanni Campagna、 Ian Hickson、 Joost de Valk、 Kevin Lawver、 L. David Baron、 Markus Mielke、 Melinda Grant、 Michael Day、 Morten Stenshorne、 Øyvind Stenhaug、 Peter Linss、 Peter-Paul Koch、 Robert O’Callahan、 Robert Stevahn、 Sergey Genkin、 Shelby Moore、 Steve Zilles、 Sylvain Galineau、 Tantek Çelik、 Till Halbach

一致性

文档惯例

一致性要求通过描述性断言和 RFC 2119 术语共同表达。术语 “MUST(必须)”、“MUST NOT(禁止)”、“REQUIRED(要求)”、“SHALL(应)”、“SHALL NOT(不得)”、“SHOULD(应当)”、“SHOULD NOT(不应当)”、“RECOMMENDED(推荐)”、“MAY(可以)” 和 “OPTIONAL(可选)” 在规范性内容中按 RFC 2119 描述解释。 但为便于阅读,本规范中这些词不会全部大写。

本规范中所有内容均为规范性内容,除非明确标注为非规范、示例和注释。[RFC2119]

本规范中的示例以“例如”开头或用 class="example" 从规范性文本中区分开,如下所示:

这是一个说明性示例。

说明性注释以“注”开头,并用 class="note" 区分开,如下所示:

注,这是一个说明性注释。

提示为规范性部分,样式突出,用 <strong class="advisement"> 区分,如下所示: 用户代理必须提供可访问性替代方案。

一致性类别

本规范定义了三种一致性类别:

样式表
CSS 样式表
渲染器
解释样式表语义并渲染文档的用户代理(UA)
创作工具
编写样式表的用户代理(UA)

如果样式表中所有使用本模块定义的语法的语句都符合通用 CSS 语法和本模块各特性的专用语法,则视为符合本规范。

如果渲染器不仅解释样式表,还能正确解析并渲染本规范定义的所有特性,则视为符合本规范。但因设备限制无法正确渲染文档不被视为不符合(如 UA 不要求在黑白显示器上渲染颜色)。

如果创作工具编写的样式表在语法上符合通用 CSS 语法和本模块各特性的语法,并符合本模块描述的其它样式表一致性要求,则视为符合本规范。

部分实现

为便于作者利用前向兼容的解析规则指定回退值,CSS 渲染器必须将任何不支持的 at-规则、属性、属性值、关键字及其它语法结构视为无效并按需忽略。尤其是,用户代理不得在多值属性声明中有选择地忽略不支持的分量却保留支持的分量:如有任意值无效(不支持的值必须视为无效),则整个声明被忽略。

不稳定与专有特性的实现

为避免与未来稳定 CSS 特性冲突,CSSWG 推荐遵循最佳实践来实现不稳定特性和专有扩展

非实验性实现

当规范进入候选推荐阶段后,可实现非实验性实现,且实现者应发布任何经证明按规范正确实现的 CR 级特性的无前缀实现。

为保证 CSS 在各实现间的互操作性,CSS 工作组要求非实验性 CSS 渲染器在发布无前缀实现前向 W3C 提交实现报告(如有必要,还包括该实现报告用到的测试用例)。提交给 W3C 的测试用例须经 CSS 工作组审核和修订。

关于提交测试用例和实现报告的更多信息,请参见 CSS 工作组网站 https://www.w3.org/Style/CSS/Test/。 有问题请联系 public-css-testsuite@w3.org 邮件列表。

索引

本规范定义的术语

引用文献定义的术语

参考文献

规范性引用

[CSS-BACKGROUNDS-3]
Elika Etemad; Brad Kemper. CSS 背景与边框模块 3 级。2024年3月11日。CR。URL: https://www.w3.org/TR/css-backgrounds-3/
[CSS-BOX-4]
Elika Etemad. CSS 盒模型模块 4 级。2024年8月4日。WD。URL: https://www.w3.org/TR/css-box-4/
[CSS-BREAK-4]
Rossen Atanassov; Elika Etemad. CSS 分片模块 4 级。2018年12月18日。WD。URL: https://www.w3.org/TR/css-break-4/
[CSS-COLOR-5]
Chris Lilley; 等. CSS 颜色模块 5 级。2024年2月29日。WD。URL: https://www.w3.org/TR/css-color-5/
[CSS-DISPLAY-3]
Elika Etemad; Tab Atkins Jr.. CSS 显示模块 3 级。2023年3月30日。CR。URL: https://www.w3.org/TR/css-display-3/
[CSS-GRID-2]
Tab Atkins Jr.; Elika Etemad; Rossen Atanassov. CSS 网格布局模块 2 级。2020年12月18日。CR。URL: https://www.w3.org/TR/css-grid-2/
[CSS-OVERFLOW-3]
Elika Etemad; Florian Rivoal. CSS 溢出模块 3 级。2023年3月29日。WD。URL: https://www.w3.org/TR/css-overflow-3/
[CSS-OVERFLOW-5]
CSS 溢出模块 5 级。编辑草案。URL: https://drafts.csswg.org/css-overflow-5/
[CSS-POSITION-3]
Elika Etemad; Tab Atkins Jr.. CSS 定位布局模块 3 级。2024年8月10日。WD。URL: https://www.w3.org/TR/css-position-3/
[CSS-SCROLL-SNAP-1]
Matt Rakow; 等. CSS 滚动捕捉模块 1 级。2021年3月11日。CR。URL: https://www.w3.org/TR/css-scroll-snap-1/
[CSS-TABLES-3]
François Remy; Greg Whitworth; David Baron. CSS 表格模块 3 级。2019年7月27日。WD。URL: https://www.w3.org/TR/css-tables-3/
[CSS-VALUES-3]
Tab Atkins Jr.; Elika Etemad. CSS 值与单位模块 3 级。2024年3月22日。CR。URL: https://www.w3.org/TR/css-values-3/
[CSS-VALUES-4]
Tab Atkins Jr.; Elika Etemad. CSS 值与单位模块 4 级。2024年3月12日。WD。URL: https://www.w3.org/TR/css-values-4/
[CSS-WRITING-MODES-4]
Elika Etemad; Koji Ishii. CSS 书写模式 4 级。2019年7月30日。CR。URL: https://www.w3.org/TR/css-writing-modes-4/
[CSS21]
Bert Bos; 等. 层叠样式表 2.1 级规范。2011年6月7日。REC。URL: https://www.w3.org/TR/CSS21/
[CSS3-ALIGN]
Elika Etemad; Tab Atkins Jr.. CSS 盒对齐模块 3 级。2023年2月17日。WD。URL: https://www.w3.org/TR/css-align-3/
[CSS3-BREAK]
Rossen Atanassov; Elika Etemad. CSS 分片模块 3 级。2018年12月4日。CR。URL: https://www.w3.org/TR/css-break-3/
[CSS3-SIZING]
Tab Atkins Jr.; Elika Etemad. CSS 盒尺寸模块 3 级。2021年12月17日。WD。URL: https://www.w3.org/TR/css-sizing-3/
[MEDIAQUERIES-5]
Dean Jackson; 等. 媒体查询 5 级。2021年12月18日。WD。URL: https://www.w3.org/TR/mediaqueries-5/
[RFC2119]
S. Bradner. RFC中用于表示需求级别的关键词。1997年3月。最佳当前实践。URL: https://datatracker.ietf.org/doc/html/rfc2119
[SELECTORS-4]
Elika Etemad; Tab Atkins Jr.. 选择器 4 级。2022年11月11日。WD。URL: https://www.w3.org/TR/selectors-4/

说明性引用

[CSS-TRANSFORMS-1]
Simon Fraser; 等. CSS 变换模块 1 级。2019年2月14日。CR。URL: https://www.w3.org/TR/css-transforms-1/
[CSS3-MULTICOL]
Florian Rivoal; Rachel Andrew. CSS 多栏布局模块 1 级。2024年5月16日。CR。URL: https://www.w3.org/TR/css-multicol-1/
[CSS3BOX]
Elika Etemad. CSS 盒模型模块 3 级。2024年4月11日。REC。URL: https://www.w3.org/TR/css-box-3/

属性索引

名称 取值 初始值 适用对象 继承 百分比 动画类型 规范顺序 计算值
column-count auto | <integer [1,∞]> auto 块级容器(不包括表包装盒) N/A 按计算值 按语法 指定值
column-fill auto | balance | balance-all balance 多列容器 N/A 离散 按语法 指定关键字
column-rule <'column-rule-width'> || <'column-rule-style'> || <'column-rule-color'> 见各单独属性 见各单独属性 见各单独属性 见各单独属性 见各单独属性 按语法 见各单独属性
column-rule-color <color> currentcolor 多列容器 N/A 按计算值类型 按语法 计算颜色
column-rule-style <line-style> none 多列容器 N/A 离散 按语法 指定关键字
column-rule-width <line-width> medium 多列容器 N/A 按计算值类型 按语法 绝对长度,按边框宽度对齐;若分隔线样式为 none 或 hidden 时为0
column-span none | <integer [1,∞]> | all | auto none 流内块级元素 N/A 离散 按语法 指定值
column-width auto | <length [0,∞]> auto 块级容器(不包括表包装盒) N/A 按计算值类型 按语法 auto 关键字或绝对长度
columns <'column-width'> || <'column-count'> 见各单独属性 见各单独属性 见各单独属性 见各单独属性 见各单独属性 按语法 见各单独属性

问题索引

此定义不够充分。
如果 column-span: 1 不等同于 column-span: none,当元素足够小时应表现为 column-span: 1 还是 column-span: none