CSS 网格布局模块 三级

W3C 工作草案

关于本文档的更多信息
本版本:
https://www.w3.org/TR/2025/WD-css-grid-3-20250917/
最新发布版本:
https://www.w3.org/TR/css-grid-3/
编辑草稿:
https://drafts.csswg.org/css-grid-3/
历史记录:
https://www.w3.org/standards/history/css-grid-3/
反馈:
CSSWG 问题仓库
规范内反馈
编辑:
Tab Atkins Jr. (Google)
Elika J. Etemad / fantasai (Apple)
Jen Simmons (Apple)
Brandon Stewart (Apple)
前编辑:
(Mozilla)
建议修改本规范:
GitHub 编辑器

摘要

本模块为 CSS 网格 容器引入了瀑布流布局作为一种额外的布局模式。

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

本文档状态

本节描述了本文档在发布时的状态。当前 W3C 出版物列表以及该技术报告的最新版本可在 W3C 标准与草案索引 中查阅。

本文档由 CSS 工作组 作为 工作草案 发布,采用了 推荐规范流程。 发布为工作草案并不意味着 W3C 及其成员的认可。

这是一个草稿文件,可能随时被更新、替换或被其他文件取代。除作为正在进行中的工作之外,不适宜引用本文件。

请通过 在 GitHub 提交 issue(推荐)反馈意见,标题中请包含规范代码 “css-grid”,格式如下: “[css-grid] …评论摘要…”。 所有问题与评论均已 存档。 或者,也可发送反馈至(已存档)公共邮件列表 www-style@w3.org

本文件受 2025年8月18日 W3C 流程文件 管辖。

本文件由遵循 W3C 专利政策 的工作组制作。 W3C 维护着一个公开的专利披露列表,用于记录与本组成果相关的专利披露; 该页面还包含专利披露的说明。 任何个人若知悉某专利且认为其包含必要权利要求,必须根据 W3C 专利政策第6节 披露相关信息。

本规范包含瀑布流布局的两种方案,欢迎对这两种方案提出反馈。

1. 引言

本节不具备规范性。

网格布局是一种 CSS 的布局模型,具有强大的控制盒子及其内容的尺寸和定位的能力。 网格布局专为二维布局优化:即在两个方向都需要内容对齐的布局场景。

网格布局示例:
		     两行项目,
		     第一行为四个项目——最后一个项目跨越了两行,
		     第二行为两个项目——第一个项目跨越了前两列——
		     以及第一行的跨列项目。
典型网格布局示例

虽然许多布局都可以用常规网格布局实现, 但在两个轴上都将项目限制在网格中,也会导致无法表达一些 Web 上常见的布局。

本模块定义了一种布局系统,去除了这种限制, 使得项目可以仅在一个轴上放入类似网格的轨道, 而在另一轴上则顺序堆叠。 项目会根据已放置项目的布局尺寸,放入剩余空间最多的列(或行)。 本模块还扩展了 CSS 网格 的网格项目放置策略, 并为 CSS 盒对齐加入了新的对齐特性。

1.1. 背景与动机

1.1.1. 自动放置项的瀑布流布局

瀑布流布局,有时也称为“水流布局”, 是一种常见的网页设计模式,其中许多项目(通常是图片或文章摘要) 被一个个地放入各个列中,其排列方式类似于石墙砌筑。 不同于 多栏布局, 后者会把内容垂直填满第一列,直到溢出到第二列, 瀑布流布局会为每个新项目选择一个列, 使其通常比后放置的项目更靠近布局顶部。

Pinterest 搜索结果页就是这种布局的典范:
瀑布流布局示例:
			          四列项目,
			          每个项目都被放入当前高度最小的列中。
典型瀑布流布局示例

在这里,每个项目的高度不同 (取决于内容和列宽), 检查 DOM 会发现 (因为视觉内容并未体现顺序) 每个项目都被放入当前高度最小的列中。

这种布局表面上看与多栏布局类似, 但它的优势在于向下滚动时, 会自然出现布局中的“后续”项目 (即搜索结果中相关性较低的项目)。

用早期的 CSS 布局模型无法实现这种布局, 除非事先知道每个项目的高度, 或借助 JavaScript 测量或定位内容。

瀑布流容器auto 自动定位项目结合, 就能实现这种瀑布流布局。

1.1.2. 一维网格布局

网格布局支持强大的轨道尺寸控制和双轴上的显式定位, 但有时布局只需要在一个维度上对齐项目。

瀑布流容器与显式定位项目结合, 可以实现这种一维网格布局。

下面这个 Douglas Graham 的例子 使用了显式定位,将每个项目放入指定的列; 但没有行, 每列中的项目则依次堆叠。 这种布局无法用 网格布局复制, 因为相邻列项目的“跨越”关系并不固定:它取决于它们的相对高度, 以及是否包含可选的横幅或广告项。 在 弹性布局中也无法复制, 因为项目的源顺序 (用于阅读、顺序导航及单栏手机布局时) 会在两列之间来回切换。
单栏布局下:
			          头部,接着可选横幅、二级导航、主内容区、广告块、和页脚。
			          双栏布局下:
			          头部和页脚分别跨越两列,
			          宽左列放横幅与主内容区,
			          窄右列放二级导航与广告块。
一维网格布局的单栏与双栏变体对比。

1.2. 值定义

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

除了各属性定义中列举的特定值, 本规范定义的所有属性也都接受 CSS 全局关键字作为属性值。 为便于阅读,未重复列出。

2. 瀑布流布局模型

瀑布流布局会将项目沿一个轴(称为网格轴)排入预定义的轨道,类似于网格布局, 但在另一个轴(称为堆叠轴)则像弹性布局那样自由流动。 与 网格布局类似,但不同于 弹性布局瀑布流布局的自动放置会将项目分布到各轨道上,使这些轨道的长度尽量接近。

网格项目的形成与块级化,与常规网格容器完全一致。

(为方便理解,网格项目网格轨道瀑布流容器中可分别称为瀑布流项目瀑布流轨道。)

除非本规范另有说明,所有 CSS 属性的行为都与常规网格容器一致。 例如,可使用order指定项目的布局顺序。

注意:支持子网格项目,但子网格仅发生在网格轴上; 详见§ 3.2 子网格

瀑布流容器是一个其内容参与瀑布流布局的盒子。 若其堆叠轴块轴,则为列瀑布流容器; 若其堆叠轴行轴,则为行瀑布流容器

瀑布流容器对比
列瀑布流
grid-template-columns: 1fr 2fr 3fr;
列瀑布流将项目沿列排列,
					     但在各列间依次分布,
					     每个项目都放入当前最短的列。
行瀑布流
grid-template-rows: 1fr 2fr 3fr;
行瀑布流将项目沿行排列,
					     但在各行间纵向分布,
					     每个项目都放入当前最短的行。

2.1. 重排序与可访问性

虽然瀑布流布局通常是向前推进的 (下一个项目会放在当前项目的下方或末端, 与自然“阅读顺序”一致), 但它也可能在这二者之间随意切换。 在简单场景下,item-tolerance属性可以帮助减少由于块轴上的微小尺寸差异导致的回溯感, 但当自动放置显式定位或跨越项目混合时, 一定程度的回溯可能会发生。

例如,下面的标记示例中, 第四项是一个跨列项目,无法放入第一行剩余的空列。 它最终被放在第一列, 这是它可以放入的最高可用空间。 接下来的几个项目,跨度为1, 会排在它“上方”的空列中, 违背了自然阅读顺序。
<section class=masonry>
  <div class=item>1</div>
  <div class=item>2</div>
  <div class="item tall">3</div>
  <div class="item wide">4</div>
  <div class=item>5</div>
  <div class=item>6</div>
  <div class=item>7</div>
</section>
<style>
.masonry {
  //FIXME display: something;
  grid-template-columns: repeat(5, auto);
}
.item { height: 50px; }
.item.wide { grid-column: span 3; }
.item.tall { height: 90px; }
</style>
此例中,第一行为项目 1、2、3、5、6,
			          其中项目 3 比其他项目稍高。
			          项目 4 跨越前三列,被放在项目 3 下方,项目 7 则嵌在项目 5 下方。
自动放置的瀑布流布局,项目高度与跨度混合
同样,显式放入特定轨道的项目会留下空隙, 后续自动放置的项目可能会被视觉上放在顺序之外的位置中。

作者应注意这些情况, 并设计尽量减少回溯的布局, 以便更好地跟随焦点和阅读顺序。 或者,如果项目没有固有顺序, 可使用reading-flow属性让 UA 对项目进行重排序, 便于阅读和线性导航。

或者对于自动放置项,这里默认应该重排序吗?

减少回溯的技巧包括:

网格布局弹性布局一样, 作者可使用order属性对项目进行重排序; 同样需注意相关问题。 详见CSS 网格布局 2 § 4 重排序与可访问性CSS 弹性盒 1 § 5.4.1 重排序与可访问性

2.2. 建立瀑布流布局

名称: display
新值: something
something
此值会让元素生成一个瀑布流容器盒子。

未在网格轴上启用子网格的瀑布流容器, 会为其内容建立一个独立格式化上下文

ISSUE(12022):我们正在寻找一个合理的display值(需包含 grid 关键词),用以表示瀑布流布局。 比如 something-gridgrid-somethinggrid somethingsomething grid。 欢迎在 issue 中提出建议。
ISSUE(12820):需要更正式地写出 grid/masonry 格式化上下文的工作方式?

3. 瀑布流轨道规范

网格轴上, 可充分使用网格布局的轨道声明能力:

但是, 自动放置的项目会对所有轨道参与尺寸分配, 不仅仅是它最终被放置的轨道; 详见§ 3.4 网格轴轨道尺寸

注意:这是因为自动放置项目必须在放置时布局, 以便每个轨道都能知道自身的“填充度” (从而决定下一个自动放置项目应放入哪个轨道); 所以轨道自身必须已经有确定尺寸, 这样项目在布局时才能知道它们的可用空间

3.1. 声明瀑布流轨道模板:grid-template-* 属性

grid-template-*grid-auto-rows/grid-auto-columns 属性 (及其简写形式) 适用于 瀑布流容器网格轴, 并像普通 网格容器 一样建立轨道。 (在 堆叠轴 上会被忽略。)

3.1.1. 内在轨道与 repeat()

是否允许内容驱动自动重复的轨道? 这样的定义是否合理? 是否也应该在网格布局中工作?[Issue #10915]

在网格布局中, 所有网格项目会在轨道尺寸确定之前被放入网格中。 这意味着auto-fill/auto-fit重复 不能包含内在尺寸轨道(如auto,无论是在repeat()函数中还是作为轨道列表的固定部分), 因为这需要布局算法已知哪些项目会分布在这些轨道上, 以确定轨道尺寸, 再决定可用空间中能容纳多少重复。

在瀑布流布局中, 由于瀑布流项目的放置与布局紧密结合且更简化, 此限制不再绝对要求。 这需要对尺寸做一点启发式定义, 但自动重复可以包含内在尺寸的轨道, 用于瀑布流容器

要确定repeat()函数的重复次数, 需通过初始化轨道尺寸(参考CSS 网格布局 2 § 12.4 初始化轨道尺寸) 并解析内在轨道尺寸(参考CSS 网格布局 2 § 12.5 解析内在轨道尺寸), 结合§ 3.4 网格轴轨道尺寸,按如下假设进行:

所有轨道都以此简化布局计算出的尺寸(包括在repeat()参数中的,取自各自单次重复) 用于确定repeat()函数的重复次数。

动机

此简化布局启发式定义为“足够好”,同时保持快速且一致。

忽略项目放置仅为让概念自洽; 在未得知所需重复数之前, 无法确定带有明确放置的项目最终会落在哪条轨道上。

将跨越项目拆分为跨度为 1 的项目, 可避免需要多次展开 repeat(), 以及同一关键字在各重复中出现不同尺寸的不合理情况。

这也让整体布局成本显著降低, 仅需考虑每种唯一轨道尺寸; 实际上甚至无需真正做任何 repeat() 展开。 例如,在 auto repeat(auto-fill, min-content auto) 中, 两个auto关键字 会在此启发式布局下解析为相同尺寸; 只需计算出 automin-content轨道尺寸, 并使用这些尺寸即可。

3.2. 子网格

子网格化允许嵌套的瀑布流容器(以及网格容器) 共享轨道尺寸。 如果父容器的相应轴为网格轴, 子网格轴将按网格容器规范从父容器获得; 如果父容器的相应轴为堆叠轴, 子网格轴则表现为 masonry

注意:如果结果导致两个轴都是 masonry, 则按瀑布流容器的双轴 masonry 模板常规解析, 即如 grid-template-columns: none; grid-template-rows: masonry

瀑布流布局中, 自动放置的子网格不会继承其父网格的线名称, 因为那会使项目的放置依赖于布局结果; 但子网格的轨道仍会与父轨道对齐。

下面是一个子网格示例
<style>
.grid {
  //FIXME: display: inline something;
  grid-template-rows: auto auto 100px;
  align-content: center;
  height: 300px;
  border: 1px solid;
}

.grid > * {
  margin: 5px;
  background: silver;
}
.grid > :nth-child(2n) {
  background: pink;
}

.grid subgrid {
  display: grid;
  grid: subgrid / subgrid;
  grid-row: 2 / span 2;
  grid-gap: 30px;
}
.grid subgrid > * { background: cyan; }
</style>
<div class="grid">
  <item>1</item>
  <item>2</item>
  <item>3</item>
  <subgrid>
    <item style="height:100px">subgrid.1</item>
    <item>sub.2</item>
    <item>s.3</item>
  </subgrid>
  <item>4</item>
  <item>5</item>
  <item style="width: 80px">6</item>
  <item>7</item>
</div>
上述子网格示例的渲染效果。

注意子网格的首项("subgrid.1")对父网格第二行的内在尺寸有贡献。 这是因为子网格指定了明确位置,所以我们知道它会占用哪些轨道。 同时注意,尝试对子网格父容器的堆叠轴应用子网格,会使子网格在其瀑布流布局行轴采用瀑布流布局。

子网格 若为瀑布流容器,可称为子瀑布流

3.3. 轨道重复:repeat()记法

本规范为repeat()记法引入了新关键字和瀑布流专属行为。

3.3.1. repeat(auto-areas)

新的auto-areas值, 用于repeat()记法, 表示需要重复的次数,以使所有显式轨道总数与相应轴上的grid-template-areas值一致。 若重复项有多个轨道,则最后一次重复会被截断以得到正确数量的轨道。

注意:auto-fit不同——后者总会至少重复一次并总是完整重复轨道列表——auto-areas的重复次数可以为零 (如果已有足够的显式轨道),且最后一次重复可为部分。

如果grid-template-areasnone, 此值表现如auto-fit

注意:此值适用于常规网格容器瀑布流容器

尚不清楚是否真的需要此值。 注意显式网格已经可根据grid-auto-columns/grid-auto-rows值灵活补齐模板区域数量。 [Issue #10854]

3.3.2. repeat(auto-fit)

瀑布流容器(以及常规网格容器)中,auto-fit表现如auto-fill, 但空轨道会被折叠。 由于放置发生在轨道尺寸确定之后,瀑布流容器会用启发式方法判断轨道是否被占用:

所有由auto-fit重复产生且按此启发式视为未占用的轨道, 都视为“空”并折叠折叠轨道不能再接受自动放置项目的定位。

注意:当使用auto-fill时, 如果有自动放置项目跨度大于 1, 且与显式定位项目混合,出现空隙小于自动放置项所需跨度, 则自动放置项有可能被放到一个使用auto-fit时会被折叠的轨道上。

3.4. 网格轴轨道尺寸

轨道尺寸与CSS 网格中的工作方式相同, 唯一区别在于确定哪些项目参与内在尺寸时:

例如,假设网格轴上有两列:

在这种情况下,A、B、C、D 都参与第一列的尺寸计算, 而第二列只有 A、B、C(没有 D)参与计算。

对于具有自动网格位置的跨越项目, 视作在每一个可能的起始位置都被放置,并据此参与尺寸计算。

举例,假设网格轴有 5 列, 中间一列为固定尺寸 100px,其他两列为 auto 尺寸。 在轨道尺寸计算时, 一个跨越 2 个轨道、内在尺寸贡献为 220px 的项目,本质上会被复制并假设存在于:

注意:该算法确保每个轨道至少足够大, 能容纳最终放置其上的所有项目, 且不会在放置与轨道尺寸间产生依赖循环。 但根据尺寸变化, 轨道可能比实际需求更大: 只有所有项目都在网格轴显式放置或所有项目尺寸相同 (或跨越项目为相同尺寸的倍数)时才能保证完全适配。

3.4.1. 子网格项目尺寸贡献

在为常规网格容器瀑布流容器计算轨道尺寸时, 子瀑布流对具有自动网格位置的项目有特殊处理:

3.4.2. 轨道尺寸优化

可以通过将具有相同跨度和放置方式的项目聚合为一个虚拟项目来优化轨道尺寸:

  1. 按以下属性将所有瀑布流项目分组为项目组
    • 项目的跨度

    • 项目的放置方式,即允许在哪些轨道放置

    • 项目的基线共享组

    注意:例如,跨度为 2 且放置在第二个轨道的项目, 与跨度为 2 且具有自动网格位置的项目分属不同组。

  2. 对每个项目组,合成一个虚拟瀑布流项目, 其内在尺寸贡献取该组所有项目贡献的最大值。

    若项目应用了基线对齐, 则将所有项目放入一个假设网格轨道,找出其共享基线和 shim, 并相应增加组的内在尺寸贡献。

  3. 将每个虚拟瀑布流项目的假设副本放置在网格轴轨道的每个可能位置, 并用这些项目运行轨道尺寸算法。 得到的轨道尺寸即为瀑布流容器的轨道尺寸。

注意:此优化应与上述轨道尺寸描述得到相同结果; 如有不同即为错误,请向 CSSWG 报告

4. 瀑布流放置

网格轴上, 项目可使用熟悉的网格定位属性语法显式放置于轨道并跨越, 自动放置则使用§ 4.4 瀑布流布局与放置算法, 将每个具有自动网格位置的项目放入当前最“短”的瀑布流轨道。

这是一个 瀑布流布局示例,演示了定位和跨越项目:
上述示例的渲染效果。

需要更好的示例!!!

4.1. 指定瀑布流项目位置:grid-column-*grid-row-* 属性

grid-column-*grid-row-* 属性 (及其简写方式) 适用于项目的网格轴, 并像常规网格布局一样实现定位。

4.2. 放置精度:item-tolerance 属性

名称: item-tolerance
值: normal | <length-percentage> | infinite
初始值: normal
适用对象: 瀑布流容器
是否继承:
百分比: 相对于 网格轴 内容盒尺寸的瀑布流容器
计算值: 一个计算后的 <length-percentage>
规范顺序: 按语法
动画类型: 按长度

瀑布流容器通过将每个瀑布流项目放入当前最少填充的瀑布流轨道来填充。 当多个轨道同为最少填充时,按顺序放置项目效果较好。 但如果轨道仅有微小高差, 不按顺序填充会显得奇怪, 因为高度差异未被认为有意义

item-tolerance属性用于指定将轨道视为“等高”的阈值, 导致按顺序填充。

<length-percentage>

瀑布流容器指定并列阈值。 如果可选位置与最短位置距离在指定范围内,则视为“并列”同好位置。

注意:初始值为“较小”距离(1em), 通常可代表“足够接近”。

normal

瀑布流布局中解析为使用值1em,在其他布局模式下为 0

infinite

指定无限并列阈值。 项目将严格按顺序分布, 完全不考虑轨道长度。

注意:此值可能导致连续项目在堆叠轴上位置相差很大, 可能让读者困惑。 若初始值(`1em`)太小, 可考虑更大值(如 `10em` 或 `50vh`)而不是 `infinite`。

1em 是合适的默认值吗?

CSSWG 欢迎对此属性更好的命名建议。[Issue #10884]

注意:我们预计未来会将此属性应用于弹性布局, 参见相关讨论

4.3. 密集放置:dense 关键字

网格布局中,grid-auto-flow: dense允许在网格项目放置算法期间回溯。 dense关键字同样允许在瀑布流放置算法期间回溯。 但由于瀑布流放置与尺寸计算紧密相关, 项目只有当目标空槽的轨道总已用尺寸与正常放置轨道一致时, 才能回溯进入兼容空位。

注意:此限制避免项目多次布局。

4.4. 瀑布流布局与放置算法

对于网格轴上的每个轨道, 维护一个运行位置,初始为零。 还要维护一个自动放置光标,初始指向第一条线。

对于顺序调整后的文档顺序中的每个项目:

  1. 如果该项目在 网格轴 上有明确网格位置, 则使用该定位。

    是否也应更新放置光标?

    否则,按以下子步骤解析其 网格轴定位:

    1. 网格轴隐式网格的第一条线开始, 找出如果项目放在该线时会跨越的所有 网格轴轨道的最大 运行位置,并记为 max_pos
    2. 对每个连续线号重复前一步, 直到项目无法再放入网格。
    3. possible lines 为所有产生最小 max_pos 的线, 以及所有 max_pos 在该值并列阈值范围内的线。
    4. 选择 possible lines 中大于等于 自动放置光标的第一条线作为项目在 网格轴上的位置; 若没有,则选第一个。
    5. 自动放置光标更新为该项目的最后一条线。
  2. 将项目放在其网格轴轨道的所有被跨越轨道的最大运行位置处。
  3. 计算该项目的包含块尺寸并布局项目。 将所有被跨越网格轴轨道的运行位置设为 max_pos + outer size + grid-gap
  4. 如果瀑布流容器使用了dense密集打包, 且布局中存在被跳过的空隙(例如因为跨越项目导致), 当前项目的尺寸若提前放置可以适配这些空隙, 并且所跨轨道的总已用尺寸与当前放置轨道一致, 则将项目放在最高的此类空隙中。 若有多个有效空隙在并列阈值范围内, 则放在最“起始”(start)的一项。 将自动放置光标运行位置回退到该项目放置前的状态。

    注意:密集打包回填时会忽略自动放置光标, 且放置后不更新光标。 如果没有合适的回填空隙,则放置方式与未指定 dense 时完全一样。

注意:该算法会选择使项目尽量靠上放置的轨道。 若有并列,则优先选最早的轨道,最近放置项目之后(如有可能),以确保即使有并列也总是“向前移动”。

4.4.1. 包含块

参与瀑布流布局网格项目包含块, 由其在网格轴上的网格区域网格容器堆叠轴上的内容盒共同形成。

4.4.2. 放置与书写模式

注意:与所有网格布局一样, 瀑布流布局与放置会受书写模式影响。 例如,使用 direction: rtl 时, 项目会从右至左放置, 无论内联轴是网格轴还是堆叠轴

下面是一个在网格轴上使用 direction: rtl 的简单示例:
<style>
  .grid {
    //FIXME display: inline something;
    direction: rtl;
    grid-template-columns: repeat(4, 2ch);
    border: 1px solid;
  }

  item { background: silver }
  item:nth-child(2n+1) {
    background: pink;
    height: 4em;
  }
  </style>
<div class="grid">
  <item>1</item>
  <item style="grid-column:span 2">2</item>
  <item>3</item>
  <item>4</item>
</div>
上述 direction: rtl 示例的渲染效果。
下面是一个在堆叠轴上使用 direction: rtl 的简单示例:
<style>
.grid {
  //FIXME display: inline something;
  direction: rtl;
  width: 10ch;
  column-gap: 1ch;
  grid-template-rows: repeat(4, 2em);
  border: 1px solid;
}

item { background: silver }
item:nth-child(2n+1) {
  background: pink;
  width: 4ch;
}
</style>
<div class="grid">
  <item>1</item>
  <item style="grid-row:span 2">2</item>
  <item>3</item>
  <item>4</item>
</div>
上述 direction: rtl 示例的渲染效果。

5. 网格容器尺寸

网格容器尺寸的工作方式与普通网格容器一致,但在堆叠轴有如下补充: 网格容器堆叠轴上的max-content 尺寸min-content 尺寸), 是该轴下瀑布流盒的尺寸, 以max-content 约束min-content 约束)计算。

这是一个简单示例
<style>
.grid {
  //FIXME display: inline something;
  grid-template-columns: 50px 100px auto;
  grid-gap: 10px;
  border: 1px solid;
}
item { background: silver; margin: 5px; }
</style>
<div class="grid">
  <item style="border:10px solid">1</item>
  <item>2</item>
  <item>3</item>
  <item style="height:50px">4</item>
  <item>5</item>
  <item>6</item>
</div>
上述网格容器内在尺寸示例的渲染效果。

6. 对齐与间距

间距(gutters)在两个轴上都支持。 在堆叠轴, 间距应用于每对相邻项目的外边距盒之间。 两个轴上的外边距不会折叠。

网格轴上,对齐与普通网格容器完全一致。

堆叠轴内容分布作用于整体内容,类似块容器的行为。 更具体地说,对齐对象瀑布流盒, 即包裹所有外边距盒的最小矩形。

瀑布流盒的范围由虚线边框标示。 (注意项目1这里有5px底边距。)

注意:这些属性在堆叠轴上只有一个唯一的对齐对象, 所以align-content / justify-content值最终都归结为startcenterend、 和基线对齐。 (normalstretch的行为与start一样, 而分布式对齐值按其回退对齐处理。) 如果网格项目堆叠轴上溢出 网格容器内容盒, 那么瀑布流盒会比网格容器内容盒更大。

堆叠轴上的对齐是否应该更复杂?具体应该如何?

6.1. 基线对齐

项目在网格轴轨道内的基线对齐与普通网格容器一致, 网格容器的基线也按该轴下普通网格容器方式确定。

基线对齐堆叠轴不支持。 该轴下网格容器的首个基线集合取每个轨道首项中的最高对齐基线, 最后一个基线集合取各轨道末项中的最低对齐基线

我们可以支持首行基线对齐。需要吗?

最后一个基线是否应该取自最后最低的项目?

7. 分页

7.1. 堆叠轴分页

每个网格轴轨道在堆叠轴上独立分页。 如果网格项目被分页, 或其前/后有强制断页, 则其所跨运行位置的轨道会被设为分页容器的尺寸,不再放其他项目。 被分割为多个片段的项目会在所有片段中保留其在网格轴上的放置。 被推送的网格项目,则会在下一个网格容器片段中重新放置。 放置会一直持续直到所有项目被放置或被推至新片段。

这是一个示例,演示了在块轴采用瀑布流布局的网格分页。 渲染如下:
块轴瀑布流布局中的分页可视化。

7.2. 网格轴分页

在另一轴采用瀑布流布局时,网格轴的分页也支持。 此时分页行为更像普通网格容器; 但分页前会有一步,确定每个项目被放入哪个网格轴轨道。

这是一个示例,演示了在瀑布流布局行轴上的网格分页。 此时断页发生在网格轴的行之间。 渲染如下:
块轴与行轴瀑布流布局下的分页可视化。

8. 绝对定位

网格对齐绝对定位后代瀑布流容器中同样支持, 与普通网格容器一致; 但在堆叠轴上,定位只存在两条线(加上auto线):

堆叠轴定义静态定位可能有用。 也许可以定义为该点所有网格轴轨道当前最大(或最小?)运行位置,或前一个项目结束处?

9. 优雅降级

通常,瀑布流设计在仅支持网格布局但不支持瀑布流布局的 UA 下也能较好降级。

这是一个示例,说明这一点。

display: grid;
display: something; /* 在不支持瀑布流布局的 UA 中会被忽略 */
grid-template-columns: 150px 100px 50px;

这将创建一个三列布局, 但如果 UA 不支持瀑布流布局, 在块轴上会有“更多空隙”。 下图为支持瀑布流时的效果:

支持瀑布流的 UA 下的渲染效果。

附录A:通用布局项流控制:item-*属性

此节可能会移至其他规范, 如[css-display-4], 因为它影响多个 display 类型。

CSS 中的多种布局模式会将子元素作为原子“项目”组织成容器内的行和/或列, 并允许作者配置它们的顺序和放置方式。 item-*属性为这些排序和放置选项提供通用控制, 封装了布局专属的flex-flowgrid-auto-flow属性。

项流控制概览
流向方案 轨道方案 值空间 描述 现有 flex 属性 现有 grid 属性
item-direction item-track auto | row | column | row-reverse | column-reverse 控制项目是按行还是按列放置,以及轨道内是起始到末尾还是末尾到起始排序。 flex-direction grid-auto-flow
item-wrap item-cross [ auto | nowrap | wrap ] || [ normal | reverse ] | wrap-reverse 控制项目在由行/列属性控制的主轴以外的轴上是否换行,如换行则规定顺序。 flex-wrap 本级引入到grid-auto-flow属性。
item-pack item-pack normal | dense || balance 配置项目如何填充轨道。 grid-auto-flow
item-tolerance item-tolerance normal | <length-percentage> | infinite 定义放置决策中的布局“容差”量。

CSSWG 仍在讨论这些属性的命名和关系。[Issue #11480]

项流主轴:item-track/item-direction

名称: item-direction, item-track
值: auto | row | column | row-reverse | column-reverse
初始值: auto
适用对象: 弹性容器, 网格容器, 瀑布流容器
是否继承:
百分比: N/A
计算值: 按指定
规范顺序: 按语法
动画类型: 离散

该属性控制项目是按行还是按列放置,以及轨道内是起始到末尾还是末尾到起始排序。

此属性有两个未决问题: a) 应叫什么,b) 它描述的是放置的主方向还是项目所在轨道的方向; 换句话说,此属性定义的主轴主放置轴还是主轨道轴。 对弹性布局网格布局这两者是一样的, 但对于瀑布流布局,主放置方向是跨其轨道的。[Issue #11480]

auto

根据布局模式,计算为rowcolumn

row

轨道方案 代表放入行(即与行轴平行的轨道/线)。 项目按起始到末尾顺序填充这些行。

流向方案 代表以行为主的项目放置, 即项目按起始到末尾放在行轴, 在弹性布局中产生弹性行, 在瀑布流布局中为列网格轨道。

column

轨道方案 代表放入列(即与块轴平行的轨道/线)。 项目按起始到末尾顺序填充这些列。

流向方案 代表以列为主的项目放置, 即项目按起始到末尾放在块轴, 在弹性布局中产生弹性列, 在瀑布流布局中为行网格轨道。

row-reverse

row相同,但顺序为末尾到起始。

column-reverse

column相同,但顺序为末尾到起始。

项目交叉轴放置模式:item-cross/item-wrap

名称: item-wrap, item-cross
值: [ auto | nowrap | wrap ] || [ normal | reverse ] | wrap-reverse
初始值: auto
适用对象: 弹性容器, 网格容器, 瀑布流容器
是否继承:
百分比: N/A
计算值: 按指定
规范顺序: 按语法
动画类型: 离散

用于控制与主轴相反方向上的项目放置。

auto

弹性容器上计算为nowrap, 其他情况计算为wrap

nowrap

项目始终在主放置轴上排列, 即使空间不足也不换行。 在弹性布局中形成单行弹性容器; 在网格布局中会在主放置轴上按需生成隐式轨道

wrap

主放置轴空间用尽时项目换行。 在弹性布局中形成多行弹性容器; 在网格布局中自动放置算法在主放置轴无显式轨道时移至下一行/列。

normal

项目在与主轨道轴相反方向上按起始到末尾排列。

弹性布局网格布局中, 此属性控制新轨道(弹性行或网格轨道)的放置方向。

瀑布流布局中, 对轨道语法控制并列(高度相同)时选哪个轨道对流向语法控制项目在轨道内填充方向。

reverse

项目在与主轨道轴相反方向上按末尾到起始排列。

wrap-reverse

计算为 wrap reverse

注意:此值为与已有flex-wrap值保持一致而设。

此属性的解释和命名依赖于item-direction/item-track对轴的解释。[Issue #11480]

项目放置打包模式:item-pack 属性

名称: item-pack
值: normal | dense || balance
初始值: normal
适用对象: 弹性容器, 网格容器, 瀑布流容器
是否继承:
百分比: N/A
计算值: 按指定
规范顺序: 按语法
动画类型: 离散

该属性控制项目在各轨道间的分布方式,具体取决于布局模式。

normal

使用当前布局模式的默认打包策略。

dense

允许回溯,将项目放入之前跳过的空位。 (这些空位可能因为前面的项目太大而未能放入。)

例如, 在弹性布局中,可以将项目放入前面仍有足够空余空间的行。

balance

弹性布局中, 此值会平衡各行(包括最后一行)的内容量, 类似text-wrap-style: balance

关于切换到瀑布流布局的一种提案是为item-pack属性添加一个collapse值。[Issue #11243]

dense打包应适用于瀑布流吗? 在瀑布流中成本更高, 因为需要在每个可能的空隙处布局元素以判断能否放下; 网格只需处理整数即可。[Issue #9326]

项目放置速记:item-flow 速记属性

名称: item-flow
值: <'item-direction'> || <'item-wrap'> || <'item-pack'> || <'item-tolerance'>
初始值: 见各属性
适用对象: 见各属性
是否继承: 见各属性
百分比: 见各属性
计算值: 见各属性
动画类型: 见各属性
规范顺序: 按语法

速记属性可在单条声明中设置所有item-*长属性

10. 致谢

感谢 Cameron McCormack 编写了瀑布流布局说明文档(其中的背景章节被引用),并向 CSSWG 做了演示, 以及 Mats Palmgren 开发了本规范的最初版本。 还要感谢所有对该特性初始提案提供反馈的人。

11. 安全注意事项

作为布局规范, 本规范未引入除一般 CSS 布局外的任何新安全注意事项。

12. 隐私注意事项

作为布局规范, 本规范未引入除一般 CSS 布局外的任何新隐私注意事项。

变更记录

第2级之后的新增内容

第2级以来新增如下功能:

近期变更

2024年10月3日工作草案以来变更如下:

一致性

文档约定

一致性要求由描述性断言和 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"> 特别样式标示,如下: UA 必须提供可访问替代方案。

测试

与本规范内容相关的测试可用 “Tests” 块标示,如本例。 任何此类测试块均为非规范性。


一致性类别

本规范定义三类兼容对象:

样式表
CSS 样式表
渲染器
解释样式表语义并渲染使用样式表的文档的UA
编辑工具
编写样式表的UA

样式表符合本规范, 需其使用本模块定义语法的所有语句均有效, 且符合通用 CSS 语法和本模块中每项特性的语法。

渲染器符合本规范, 需其除按相关规范解释样式表外,还应正确解析并渲染本规范定义的所有特性。 但因设备限制无法正确渲染文档不视为不兼容 UA。(如 UA 不要求在单色显示器上渲染颜色。)

编辑工具符合本规范, 需其编写的样式表在语法上符合通用 CSS 语法和本模块所有特性语法, 并满足本模块样式表的所有其他一致性要求。

部分实现

为便于作者利用向前兼容的解析规则指定回退值, CSS 渲染器必须将所有不支持的 at-规则、属性、属性值、关键字及其他语法结构视为无效(并按需忽略)。 特别是,UA不得在对多值属性声明进行解析时,仅忽略不支持的组件值而保留支持值:任何值被视为无效时,CSS 要求整个声明被忽略。

不稳定与专有特性的实现

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

非实验性实现

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

为确保 CSS 在各实现间的互操作性, CSS 工作组要求非实验性 CSS 渲染器在发布无前缀实现前向 W3C 提交实现报告(如有需要还应提交用于该报告的测试用例)。 向 W3C 提交的测试用例需经 CSS 工作组审核与修正。

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

索引

本规范定义的术语

引用定义的术语

参考文献

规范性引用

[CSS-ALIGN-3]
Elika Etemad; Tab Atkins Jr.. CSS盒对齐模块3级。2025年3月11日。WD。URL: https://www.w3.org/TR/css-align-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日。FPWD。URL: https://www.w3.org/TR/css-break-4/
[CSS-CASCADE-5]
Elika Etemad; Miriam Suzanne; Tab Atkins Jr.. CSS层叠与继承5级。2022年1月13日。CR。URL: https://www.w3.org/TR/css-cascade-5/
[CSS-DISPLAY-4]
Elika Etemad; Tab Atkins Jr.. CSS显示模块4级。2024年12月19日。FPWD。URL: https://www.w3.org/TR/css-display-4/
[CSS-FLEXBOX-1]
Tab Atkins Jr.; 等。CSS弹性盒布局模块1级。2018年11月19日。CR。URL: https://www.w3.org/TR/css-flexbox-1/
[CSS-GAPS-1]
Kevin Babbitt. CSS间隙装饰模块1级。2025年4月17日。FPWD。URL: https://www.w3.org/TR/css-gaps-1/
[CSS-GRID-1]
Tab Atkins Jr.; 等。CSS网格布局模块1级。2025年3月26日。CRD。URL: https://www.w3.org/TR/css-grid-1/
[CSS-GRID-2]
Tab Atkins Jr.; 等。CSS网格布局模块2级。2025年3月26日。CRD。URL: https://www.w3.org/TR/css-grid-2/
[CSS-SIZING-3]
Tab Atkins Jr.; Elika Etemad. CSS盒尺寸模块3级。2021年12月17日。WD。URL: https://www.w3.org/TR/css-sizing-3/
[CSS-TEXT-4]
Elika Etemad; 等。CSS文本模块4级。2024年5月29日。WD。URL: https://www.w3.org/TR/css-text-4/
[CSS-VALUES-3]
Tab Atkins Jr.; Elika Etemad. CSS值与单位模块3级。2024年3月22日。CRD。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/
[CSS2]
Bert Bos; 等。层叠样式表2级修订1 (CSS 2.1) 规范。2011年6月7日。REC。URL: https://www.w3.org/TR/CSS2/
[RFC2119]
S. Bradner. RFC中用于指示需求级别的关键词。1997年3月。最佳当前实践。URL: https://datatracker.ietf.org/doc/html/rfc2119

补充性引用

[CSS-MULTICOL-1]
Florian Rivoal; Rachel Andrew. CSS多栏布局模块1级。2024年5月16日。CR。URL: https://www.w3.org/TR/css-multicol-1/
[CSS-WRITING-MODES-3]
Elika Etemad; Koji Ishii. CSS书写模式3级。2019年12月10日。REC。URL: https://www.w3.org/TR/css-writing-modes-3/

属性索引

名称 初始值 适用对象 继承 百分比 动画类型 规范顺序 计算值
item-cross [ auto | nowrap | wrap ] || [ normal | reverse ] | wrap-reverse auto 弹性容器,网格容器,瀑布流容器 N/A 离散 按语法 按指定
item-direction auto | row | column | row-reverse | column-reverse auto 弹性容器,网格容器,瀑布流容器 N/A 离散 按语法 按指定
item-flow <'item-direction'> || <'item-wrap'> || <'item-pack'> || <'item-tolerance'> 见各属性 见各属性 见各属性 见各属性 见各属性 按语法 见各属性
item-pack normal | dense || balance normal 弹性容器,网格容器,瀑布流容器 N/A 离散 按语法 按指定
item-tolerance normal | <length-percentage> | infinite normal 瀑布流容器 相对于瀑布流容器的网格轴内容盒尺寸 按长度 按语法 计算后的 <length-percentage> 值
item-track auto | row | column | row-reverse | column-reverse auto 弹性容器,网格容器,瀑布流容器 N/A 离散 按语法 按指定
item-wrap [ auto | nowrap | wrap ] || [ normal | reverse ] | wrap-reverse auto 弹性容器,网格容器,瀑布流容器 N/A 离散 按语法 按指定

问题索引

自动放置项这里是否应默认重排序?
ISSUE(12022):我们正在寻找一个合理的display值(需包含 grid 关键词),用以表示瀑布流布局。 比如 something-gridgrid-somethinggrid somethingsomething grid。 欢迎在 issue 中提出建议。
ISSUE(12820):需要更正式地写出 grid/masonry 格式化上下文的工作方式?
是否允许内容驱动自动重复的轨道? 这样的定义是否合理? 是否也应该在网格布局中工作?[Issue #10915]
尚不清楚是否真的需要此值。 注意显式网格已经可根据grid-auto-columns/grid-auto-rows值灵活补齐模板区域数量。[Issue #10854]
需要更好的示例!!!
1em 是合适的默认值吗?
CSSWG 欢迎对此属性更好的命名建议。[Issue #10884]
放置光标也该更新吗?
堆叠轴上的对齐是否应该更复杂?具体应该如何?
我们可以支持首行基线对齐。需要吗?
最后一个基线是否应该取自最后最低的项目?
堆叠轴定义静态定位可能有用。 也许可以定义为该点所有网格轴轨道当前最大(或最小?)运行位置,或前一个项目结束处?
此节可能会移至其他规范, 如[css-display-4], 因为它影响多个display类型。
CSSWG 仍在讨论这些属性的命名和关系。[Issue #11480]
此属性有两个未决问题: a) 应叫什么,b) 它描述的是放置的主方向还是项目所在轨道的方向; 换句话说,此属性定义的主轴主放置轴还是主轨道轴。 对弹性布局网格布局这两者是一样的, 但对于瀑布流布局,主放置方向是跨其轨道的。[Issue #11480]
此属性的解释和命名依赖于item-direction/item-track对轴的解释。[Issue #11480]
关于切换到瀑布流布局的一种提案是为item-pack属性添加一个collapse值。[Issue #11243]
dense打包应适用于瀑布流吗? 在瀑布流中成本更高, 因为需要在每个可能的空隙处布局元素以判断能否放下; 网格只需处理整数即可。[Issue #9326]