CSS 网格布局模块第 3 级

W3C 工作草案

关于本文件的更多详细信息
此版本:
https://www.w3.org/TR/2025/WD-css-grid-3-20250207/
最新发布版本:
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 编辑器

摘要

本模块引入了 masonry 布局作为 CSS 网格容器的附加布局模式。

CSS 是一种描述结构化文档(如 HTML 和 XML)在屏幕、纸张等上呈现的语言。

本文件的状态

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

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

这是一份草案文件, 可能随时被其他文件更新、替换 或废弃。 将本文档作为正在进行的工作以外的任何形式引用都是不合适的。

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

本文档受 2023 年 11 月 3 日 W3C 流程文档的约束。

本文档由一个在 W3C 专利政策下运作的小组制定。 W3C 维护一份与该小组交付成果相关的任何专利披露的公开列表; 该页面还包含披露专利的说明。 任何实际知晓某项专利包含其认为是必要权利要求的个人, 必须根据 W3C 专利政策第 6 条披露该信息。

本规范代表了砌体式布局提案的两种变体。欢迎对这些替代方案提供反馈。

1. 介绍

本节不是规范性内容。

网格布局是一个强大的 CSS 布局模型,能够控制盒子及其内容的大小和定位。 网格布局针对二维布局进行了优化: 这些布局在两个维度上都希望内容对齐。

网格布局示例:
		     两行项目,
		     第一行为四个项目——最后一个跨越两行,
		     第二行为两个项目——
		     第一个跨越前两列——
		     加上来自第一行的跨越项目。
代表性的网格布局示例

尽管许多布局可以通过常规的网格布局表示, 但在两个轴上限制项目到网格中也使得 一些常见的网页布局无法实现。

本模块定义了一种布局系统,消除了这一限制, 使得项目可以仅在一个轴上放置到类似网格的轨道中, 同时在另一个轴上一个接一个地堆叠它们。 项目根据已放置项目的布局大小, 被放置到具有最多剩余空间的列(或行)中。 本模块还扩展了 CSS 网格,引入了这种新的网格项目 放置策略 和 CSS 盒子对齐,提供了新的对齐特性。

1.1. 背景和动机

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

砖石布局,有时也称为“瀑布布局”, 是一种常见的网页设计模式,多个项目—— 通常是图像或短文章摘要—— 以一种松散地类似于石砌的方式, 一个接一个地放置到列中。 与 多列布局不同, 在该布局中,内容垂直放置在第一列, 直到必须溢出到第二列,砖石布局 为每个新项目选择一列, 使得它通常更靠近布局的顶部,而不是稍后放置的项目。

Pinterest 搜索结果页面就是这一布局的示例:
砖石布局示例:
			          四列项目,
			          每个项目被放置到当前高度最小的列中。
代表性的砖石布局示例

在这里,每个项目的高度不同 (取决于内容和列的宽度), 检查 DOM 可以揭示 (因为视觉内容本身没有排序的指示) 每个项目已被放置到当前高度最小的列中。

这种布局表面上看起来类似于多列布局; 但它的优势在于向下滚动 自然会导致布局中的“后面”项目 (也就是在搜索结果中相关性较低的项目)出现。

除非你预先知道每个项目的高度, 否则无法使用早期的 CSS 布局模型实现这种布局, 或使用 JavaScript 进行内容测量或放置。

砌体容器自动定位的项目一起使用 会产生这种类型的砌体布局。

1.1.2. 一维网格布局

网格布局允许在两个轴上进行强大的轨道大小调整和显式放置, 但有时布局只需要在一个维度上对齐其项目。

砌体容器与显式定位的项目一起使用 允许这种类型的一维网格布局。

Douglas Graham 的这个例子 使用显式定位将每个项目放置到其分配的列中; 但是没有行。 相反,每列中的项目一个接一个地堆叠。 这种布局无法在网格布局中复制,因为相邻列中项目之间的“跨越”关系 不是固定的:它取决于它们的相对高度 以及是否包含可选的横幅或广告项目。 它也无法在弹性布局中复制,因为项目的源顺序 (用于阅读、顺序导航和单列手机布局) 在两列之间来回切换。
在单列布局中:
                              页眉,后跟可选横幅、二级导航、
                              主要内容区域、广告块,最后是页脚。
                              在双列布局中:
                              页眉跨越顶部两列,
                              页脚跨越底部两列,
                              在较宽的左列中,可选横幅后跟主要内容区域,
                              在较窄的左列中,二级导航后跟广告块。
一维网格布局的单列和双列变体的比较。

1.2. 值定义

本规范遵循 CSS 属性 定义规范,引用自 [CSS2],使用 值定义语法,引用自 [CSS-VALUES-3]。 本规范未定义的值类型在 CSS 值与单位中定义 [CSS-VALUES-3]。 与其他 CSS 模块的组合可能扩展这些值类型的定义。

除了定义中的特定属性值外, 本规范定义的所有属性 还接受 CSS 全局关键字 作为其属性值。 为了可读性,未明确重复这些关键字。

2. 砌体布局模型

砌体布局 将项目布局到预定义的轨道中,类似于 网格布局 在一个轴上 (称为 网格轴), 但在另一个轴上像 弹性布局 一样自由流动 (称为 堆叠轴)。 类似于 网格布局,与 弹性布局 不同,砌体布局 的自动放置 将项目分布在轨道上,以保持这些轨道的长度尽可能相似。

网格 项目 的形成和 块化 与常规的 网格容器 完全相同。

(为清晰起见,网格项目网格轨道砌体容器 可以 被称为 砌体项目砌体轨道.)

除非本规范另有说明,否则所有 CSS 属性的工作方式与常规的 网格容器 相同。 例如,顺序 可用于指定 项目的不同布局顺序。

注意: 支持子网格项目, 但子网格仅在 网格 轴 中发生; 有关详细信息,请参见 § 3.2 子网格

一个 砌体容器 是一个其内容参与 砌体布局 的框。 如果其 堆叠轴块轴,则 砌体容器 是一个 列砌体容器, 或者如果其 堆叠轴行内轴,则是一个 行砌体容器

比较砌体容器
列砌体
grid-template-columns: 1fr 2fr 3fr;
列砌体将项目按列布局,但跨列排序,将每个项目放置在当时最短的列中。
行砌体
grid-template-rows: 1fr 2fr 3fr;
行砌体将项目按行布局,但跨行向下排序,将每个项目放置在当时最短的行中。

2.1. 重新排序与可访问性

尽管砌体布局 通常以向前的方向进行 (将下一个项目放置在当前项目的下方或末尾, 与自然的“阅读顺序”相匹配), 但它可以在这两种方式之间以看似任意的方式切换。 在简单情况下,item-slack 属性可以帮助减少 在块轴中由于微小的尺寸差异 而在布局自动放置项目时产生的回溯感。 但是当自动放置显式放置或跨越项目混合使用时, 可能会发生一定程度的回溯。

例如,在下面的标记示例中, 第四个项目是一个跨栏项目,它不适合 第一行剩余的空列。 它最终被放置到第一列中, 这是它能容纳的最高可用空间。 接下来的几个跨度为 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:masonry or 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 属性,允许用户代理重新排序项目 以便于阅读和线性导航。

或者,是否应该将重新排序 作为自动放置项目的默认行为?

减少回溯的技术包括:

网格布局弹性布局一样, 作者可以使用 order 属性 来重新排序项目; 同样的注意事项也适用。 请参阅 《CSS 网格布局 2》 § 4 重新排序与可访问性《CSS 弹性盒模型 1》 § 5.4.1 重新排序与可访问性

2.2. 建立砌体式布局

问题(11593):我们仍在讨论使用何种语法开关来建立砌体式布局。 目前的提案包括:

3. 砌体轨道规范

网格轴中, 网格布局的全部功能都可用于轨道规范:

但是, 自动放置的项目会为所有轨道贡献大小, 而不仅仅是它们最终放置到的轨道; 请参阅§ 3.4 网格轴轨道大小调整

注意:这是因为自动放置的项目必须在放置时进行布局, 以便每个轨道都知道它有多“满” (因此哪个轨道应该接收下一个自动放置的项目); 因此,轨道本身必须已经具有确定的大小, 以便项目在布局期间知道它们的可用空间

3.1. 声明砌体式轨道模板:grid-template-* 属性

grid-template-*grid-auto-rows/grid-auto-columns 属性 (及其简写形式) 应用于砌体容器网格轴,并 像在常规网格容器上一样建立轨道。 (它们在堆叠轴中被忽略。)

初始轨道列表应该是什么?[问题 #10869]

3.1.1. 固有轨道和 repeat()

我们是否应该允许基于内容的自动重复轨道? 这对于它们来说是一个合理的定义吗? 它们是否也应该以某种方式在网格布局中工作?[问题 #10915]

在网格布局中, 所有网格项目都在网格轨道确定大小之前放置在网格中。 这意味着 auto-fill/auto-fit 重复 不能包含固有大小的轨道,例如 auto(无论是在 repeat() 函数中还是在轨道列表的固定部分中与它一起), 因为这将需要布局算法 已经确定哪些项目将进入这些轨道, 以确定轨道有多大, 以确定可用空间中适合多少次重复。

在砌体式布局中, 由于砌体式项目的放置和布局是相互交织且有所简化的, 因此不再严格要求此限制。 它需要一个稍微启发式的大小定义, 但是自动重复可以砌体式容器中包含固有大小的轨道 (并且 masonry-template-tracks 的初始值就使用了这个!)。

要确定 repeat() 函数解析到的重复次数, 请按照§ 3.4.2 优化的轨道大小调整中的定义运行布局, 并进行以下更改:

然后,任何固有大小的轨道都被视为具有通过此简化布局计算的大小 (包括 repeat() 参数中的那些, 从其对应的单个重复中获取) ,以便确定 repeat() 函数解析到的重复次数。

动机

这种简化的布局启发式方法被定义为“足够好”, 同时保持快速和一致。

忽略放置只是为了使概念连贯; 在知道需要多少次重复之前, 无法判断具有确定放置的项目 最终会进入哪个轨道。

通过将跨越项目切成跨度为 1 的项目, 可以避免多次展开 repeat() 的可能需要, 以及在重复中获得相同关键字的不同大小的不连贯可能性。

它还使整个布局的成本显着降低, 因为只需要考虑每个唯一的轨道大小; 甚至实际上不需要进行任何 repeat() 展开。 也就是说,在 auto repeat(auto-fill, min-content auto) 中, 两个 auto 关键字 在此启发式布局下都将解析为相同的大小; 只需弄清楚 masonry-template-tracks: automasonry-template-tracks: min-content 各自会产生什么结果, 并使用这些大小。

3.2. 子网格

子网格化 允许嵌套的砌体式容器(和网格容器) 共享轨道大小。 如果父容器的相应轴是网格轴, 则子网格化的轴从父容器获取,如网格容器所指定; 如果父容器的相应轴是堆叠轴, 则子网格化的轴的行为类似于 masonry

注意:如果这导致两个轴都为 masonry, 则按照具有双轴 masonry 模板的砌体式容器的常规方式进行解析, 即其行为类似于 grid-template-columns: none; grid-template-rows: masonry

砌体式布局中, 自动放置的子网格不从其父网格继承任何行名称, 因为这将使项目的放置 依赖于布局结果; 但是子网格的轨道仍然像往常一样与父网格的轨道对齐。

这是一个子网格示例
<style>
.grid {
    //FIXME: display: inline-grid; 或其他
    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)

repeat() 表示法的新 auto-areas 值表示显式轨道总数与相应轴上生效的 grid-template-areas / masonry-template-areas 值匹配所需的重复次数。 如果为重复列出了多个轨道,则最终重复将根据需要截断以产生正确的轨道数。

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

如果 grid-template-areas / masonry-template-areasnone, 则此值的行为类似于 auto-fit

注意:此值既适用于常规网格容器,也适用于砌体容器

尚不清楚我们是否真的需要这个值。 请注意,显式网格已经根据需要从 grid-auto-columns/grid-auto-rows/masonry-auto-tracks 中获取值,以匹配模板区域的数量。[Issue #10854]

3.3.2. repeat(auto-fit)

砌体容器中 (与常规网格容器中一样)auto-fit 的行为类似于 auto-fill, 但空轨道会折叠。 但是,由于放置发生在轨道大小调整之后,砌体容器使用启发式方法 来确定轨道是否会被占用:

所有由 auto-fit 重复产生并被此启发式方法视为空闲的轨道都被假定为“空的”并被折叠。 一个折叠的轨道不能接受自动放置项目的放置。

注意:如果存在跨度大于 1 的自动放置项目与显式放置的项目混合,并且留下的间隙对于自动放置的项目来说太小,则当使用 auto-fill 时,自动放置的项目可能会被放置在某个轨道中,而如果使用 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. 对于每个项目组,合成一个虚拟砌体项目,该项目具有该组中项目之间每个固有尺寸贡献的最大值。

    如果项目应用基线对齐, 则通过将所有项目放置到单个假设的网格轨道中并找到它们的共享基线和垫片来确定虚拟砌体项目的基线。 相应地增加组的固有尺寸贡献。

  3. 将每个虚拟砌体项目的假设副本放置到网格轴轨道中项目可能占据的每个位置, 并使用这些项目运行轨道尺寸调整算法。 生成的轨道大小即为砌体容器的轨道大小。

注意:此优化应与上面的轨道尺寸调整描述给出相同的结果; 如果不同,则这是一个错误,请向 CSSWG 报告

4. 瀑布流布局

网格轴中, 项目可以显式放置到轨道中,并使用熟悉的网格放置属性的语法来跨越它们。 然而,自动放置使用§ 4.3 砌体布局和放置算法, 将每个具有自动网格位置的项目放置到可用的“最短”砌体轨道中。

这是一个砌体布局示例,演示了放置和跨越项目:
上面示例的渲染。

需要一个更好的例子!!!

4.1. 指定砌体项目放置:grid-column-*grid-row-* 属性

grid-column-*grid-row-* 属性 (及其简写) 应用于项目的网格轴,并像常规网格布局一样建立放置。

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

Name: item-slack
Value: <length-percentage> | infinite
Initial: 1em
Applies to: 砌体容器
Inherited: no
Percentages: 相对于砌体容器网格轴内容框大小
Computed value: 计算后的 <length-percentage>
Canonical order: per grammar
Animation type: as length

砌体容器通过将每个砌体项目放置在当前填充最少的砌体轨道中来进行填充。 当多个轨道并列为填充最少时, 按顺序放置项目看起来不错。 但是如果轨道的高度差异非常小, 让它们不按顺序填充可能会看起来很奇怪, 因为高度差异不会被认为是有意义的不同。

item-slack 属性指定了将轨道视为“相同高度”的阈值, 从而使它们按顺序填充。

<length-percentage>

指定砌体容器并列阈值。 如果放置位置与最短位置之间的距离在指定距离之内, 则认为它们同样好(“并列”)。

注意:初始值是一个“小”距离 (1em), 它可能适合表示“足够接近”。

infinite

指定一个无限的并列阈值。 这使得项目严格按照顺序分布, 完全不考虑轨道的长度。

注意:此值可能导致连续的项目被放置在堆叠轴中截然不同的位置, 这可能会让读者感到困惑。 如果初始值 (`1em`) 太小, 请考虑使用更大的值(例如 `10em` 或 `50vh`) 而不是 `infinite`。

1em 是正确的默认值吗?

4.3. 砌体布局和放置算法

对于网格轴中的每个轨道, 保留一个初始化为零的运行位置。 同时维护一个自动放置光标, 初始指向第一行。

对于按顺序修改的文档顺序中的每个项目:

  1. 如果项目在网格轴中具有确定的网格位置, 则使用该放置。

    这是否也应该更新放置光标?

    否则,使用以下子步骤解析其网格轴放置:

    1. 隐式网格中的第一个网格轴线开始, 找到如果项目放置在此行,它将跨越的网格轴轨道的最大运行位置, 并将此位置称为 max_pos
    2. 对每个连续的行号重复上一步, 直到项目不再适合网格内部。
    3. possible lines 为导致最小 max_pos 的行, 以及所有导致 max_pos 在此 max_pos并列阈值之内的行。
    4. 选择 possible lines 中大于或等于自动放置光标的第一行作为项目在网格轴中的位置; 如果没有这样的行,则选择第一个。
    5. 自动放置光标更新为指向项目的最后一行。
  2. 将项目放置在其网格轴轨道中, 位于其跨越的轨道的运行位置的最大值处。
  3. 计算项目包含块的大小,然后布局项目。 将跨越的网格轴轨道的运行位置设置为 max_pos + 外部大小 + grid-gap

注意:此算法选择的轨道 将导致项目尽可能高地放置。 如果出现平局,它会选择最早的此类轨道,可能的情况下,在最近放置的项目之后 (确保即使在出现平局的情况下它也始终“向前移动”)。

4.3.1. 包含块

参与瀑布流布局网格项包含块由其在网格轴中的网格区域网格容器堆叠轴中的内容框构成。

4.3.2. 放置与书写模式

注意:与所有网格布局一样, 瀑布流布局和放置对书写模式敏感。 例如,对于 direction: rtl(从右到左), 项目是从右向左放置,而不是从左向右, 无论内联轴是网格轴还是堆叠轴

这是一个在网格轴中使用 direction: rtl 的简单示例
<style>
    .grid {
    //FIXME display: inline-grid; or 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-grid; or 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. 网格容器的尺寸设置

网格容器尺寸调整与常规网格容器的工作方式相同,但对堆叠轴有以下补充: 网格容器堆叠轴中的最大内容尺寸最小内容尺寸)是指在该轴向上,当瀑布流盒最大内容约束最小内容约束)下确定尺寸时的大小。

这是一个简单的示例
<style>
        .grid {
          //FIXME display: inline-grid; or 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. 对齐与间距

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

网格轴中,对齐的工作方式与常规网格容器中的相同。

堆叠轴中,内容分布应用于 整个内容,类似于其在块容器中的行为。 更具体地说,对齐主体瀑布流盒, 它是包围所有网格项外边距盒的最小矩形。

瀑布流盒的范围由虚线边框指示。 (请注意,此处项目 1 的底部外边距为 5px。)

注意:堆叠轴中,这些属性始终只有一个对齐主体, 因此唯一的 align-content / justify-content 值可归结为 startcenterend基线对齐。 (normalstretch 的行为与 start 相同, 并且分布式对齐值的行为与其回退对齐相同。) 如果网格项堆叠轴中溢出网格容器内容框, 那么瀑布流盒将 大于网格容器内容框

堆叠轴中的对齐是否应该更复杂一些? 应该是什么样的?

6.1. 堆叠轴中的基线对齐

项目基线对齐网格轴轨道内的运作方式与常规网格容器相同, 并且网格容器的基线在该轴上的确定方式与常规网格容器相同。

基线对齐堆叠轴中不受支持。 网格容器在此轴上的第一个基线集 由第一个被占用轨道中第一个网格项对齐基线生成, 最后一个基线集由最后放置的网格项生成。

我们可以支持第一行中的基线 对齐。我们想要这样做吗?

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

7. 片段化

7.1. 堆叠轴中的片段化

每个网格轴轨道在堆叠轴中独立分片。 如果一个网格项被分片, 或者在其之前/之后有强制中断, 那么它在网格轴中跨越的轨道的运行位置将被设置为分片容器的大小,以便不会在这些轨道中放置更多项目。 一个被分割成多个分片的项目 为其所有分片保留其在网格轴中的位置。 然而,一个被推后的网格项, 会被下一个网格容器分片重新放置。 放置将继续,直到所有项目都被放置或推送到新的分片。

这是一个示例,说明了在其块轴中具有瀑布流布局的网格的分片。 它渲染如下:
块轴瀑布流布局中分片的可视化。

7.2. 网格轴中的片段化

在另一个轴上使用瀑布流布局时,也支持在网格轴中进行分片。 在这种情况下,分片的行为更像在常规的网格容器中; 然而,在发生分片之前,有一个单独的步骤来确定每个项目放置到哪个网格轴轨道中。

这是一个示例,说明了在其内联轴中具有瀑布流布局的网格的分片。 在这种情况下,中断发生在网格轴行之间。 它渲染如下:
块轴中使用内联轴瀑布流布局的分片可视化。

8. 绝对定位

网格对齐的绝对定位后代瀑布流容器中的支持方式与常规网格容器相同; 然而,在堆叠轴中,(除了 auto 线之外)仅存在两条线用于放置:

堆叠轴中定义静态位置可能很有用。 也许可以将其定义为该点网格轴轨道的最大(或最小?)当前运行位置?或者是它前面项目的末尾?

9. 优雅降级

通常,在支持网格布局但不支持瀑布流布局的用户代理 (UA) 中,瀑布流设计可以很好地降级。

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

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

这将创建一个包含三列的布局, 但如果 UA 不支持瀑布流布局,则在块轴中会有“更多间隙”。 作为比较,以下是支持瀑布流布局时的样子:

在支持瀑布流布局的 UA 中渲染示例。

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

此部分可能会移至其他规范, 例如 [css-display-4], 因为它影响多种显示类型。

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-slack item-slack normal | <length-percentage> | infinite 定义放置决策中特定于布局的“松弛”量。

CSSWG 仍在研究这些属性应如何命名和组合在一起。 [问题 #11480]

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

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

此属性控制项目是按行还是按列放置, 以及在这些轨道内它们是按从头到尾还是从尾到头的顺序排列。

关于此属性有两个悬而未决的争论: a) 它应该叫什么名字以及 b) 它描述的是主要放置方向, 还是放置项目的轨道的方向; 换句话说,此属性定义的主轴主放置轴还是主轨道轴。 这些对于弹性布局网格布局是相同的, 但对于瀑布流布局则不同,其主要放置方向 是横跨其轨道。 [问题 #11480]

auto

根据布局模式计算为 rowcolumn

row

面向轨道的选项 表示放置到行中, 即平行于内联轴的轨道或线。 在弹性布局网格布局中,项目按内联轴从头到尾的顺序放置, 在瀑布流布局中,项目按块轴从头到尾的顺序放置。

面向流的选项 表示行优先的项目放置, 即在内联轴中从头到尾放置项目, 在弹性布局中产生弹性行线, 在瀑布流布局中产生列网格轨道。

column

面向轨道的选项 表示放置到列中, 即平行于块轴的轨道或线。 在弹性布局网格布局中,项目按块轴从头到尾的顺序放置, 在瀑布流布局中,项目按内联轴从头到尾的顺序放置。

面向流的选项 表示行优先的项目放置, 即在内联轴中从头到尾放置项目, 在弹性布局中产生弹性行线, 以及在瀑布流布局中的列网格轨道。

row-reverse

row 相同, 但使用从尾到头的放置顺序。

column-reverse

column 相同, 但使用从尾到头的放置顺序。

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

名称: item-wrapitem-cross
取值: [ auto | nowrap | wrap ] || [ normal | reverse ] | wrap-reverse
初始值: auto
适用于: 弹性容器网格容器瀑布流容器
继承性:
百分比: 不适用
计算值: 如指定
规范顺序: 按语法
动画类型: 离散

控制与主轴相反的轴上的放置。

auto

弹性容器上计算为 nowrap, 在其他所有元素上计算为 wrap

nowrap

项目将永远放置在主放置轴中, 即使空间不足。 在弹性布局中,这会创建一个单行弹性容器; 在网格布局中,这会在必要时在主放置轴中创建隐式轨道

wrap

主放置轴空间不足时,项目会换行。 在弹性布局中,这会创建一个多行弹性容器; 在网格布局中,当主放置轴中的显式轨道用尽时,自动放置算法会移动到下一行/列。

normal

项目在与主轨道轴相反的轴上按从头到尾的顺序放置。

reverse

项目在与主轨道轴相反的轴上按从尾到头的顺序放置。

wrap-reverse

计算为 wrap reverse

注意:此值的存在是为了与现有的 flex-wrap 值保持一致。

此属性的解释和命名取决于 item-direction/item-track 的轴的解释。[问题 #11480]

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

名称: item-pack
取值: normal | dense || balance
初始值: normal
适用于: 弹性容器网格容器瀑布流容器
继承性:
百分比: 不适用
计算值: 如指定
规范顺序: 按语法
动画类型: 离散

此属性以特定于布局的方式控制项目如何在轨道之间分布。

normal

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

dense

允许回溯以将项目放置在先前跳过的空间中。 (这些空间可能因为先前的项目对于这些空间来说太大了而存在。)

例如, 在弹性布局中,这允许将项目放置在仍有足够剩余空间的先前行上。

balance

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

切换到瀑布流布局的提案之一是向此 item-pack 属性添加一个 collapse 值。 [问题 #11243]

dense 打包是否应适用于瀑布流? 在瀑布流中,这要昂贵得多, 因为您必须在每个可能的间隙位置布置元素, 以查看它是否足够短以适合; 而网格只需处理一些整数即可。[问题 #9326]

项目放置简写:item-flow 简写

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

速记属性在单个声明中设置其所有 item-* 普通属性

10. 致谢

感谢 Cameron McCormack 编写了瀑布流布局解释器文档(背景章节即摘自该文档)并将其提交给 CSSWG,感谢 Mats Palmgren 开发了此规范的原始版本。还要感谢所有对此功能初始提案提供反馈的人。

11. 安全注意事项

作为一项布局规范, 本规范除 CSS 布局通常公开的安全注意事项外, 未引入新的安全注意事项。

12. 隐私注意事项

作为一项布局规范, 本规范除 CSS 布局通常公开的隐私注意事项外, 未引入新的隐私注意事项。

变更

自 Level 2 以来的新增内容

Level 2 以来,已添加以下功能:

近期变更

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">与其他规范文本区分开,像这样: 用户代理必须提供可访问的替代方案。

测试

与本规范内容相关的测试可以在像这样的“测试”块中记录。 任何这样的块都是非规范性的。


一致性类别

对本规范的符合性定义为三个符合性类别:

样式表
一个CSS样式表
渲染器
一个用户代理,它解释样式表的语义并渲染使用它们的文档。
创作工具
一个用户代理,它编写样式表。

如果样式表的所有语句使用本模块中定义的语法都是根据通用CSS语法和本模块中定义的每个特性的个别语法有效,则该样式表符合本规范。

如果渲染器在解释样式表时符合适当的规范,并支持本规范定义的所有特性,正确解析它们并相应地渲染文档,则该渲染器符合本规范。然而,用户代理因设备限制而无法正确渲染文档并不意味着该用户代理不符合规范。(例如,用户代理不要求在单色显示器上渲染颜色。)

如果创作工具编写的样式表根据通用CSS语法和本模块中每个特性的个别语法是语法正确的,并满足本模块中描述的样式表的所有其他符合性要求,则该创作工具符合本规范。

部分实现

为了使作者能够利用向前兼容的解析规则来分配回退值,CSS渲染器必须将任何没有可用支持级别的at-rules、属性、属性值、关键字和其他语法结构视为无效(并根据需要忽略)。特别是,用户代理不得在单一多值属性声明中选择性忽略不支持的组件值,而只考虑支持的值:如果任何值被视为无效(如不支持的值必须),CSS要求整个声明被忽略。

不稳定和专有功能的实现

为了避免与未来稳定的CSS特性发生冲突,CSS工作组建议遵循最佳实践来实现不稳定特性和专有扩展

非实验性实现

一旦规范达到候选推荐阶段,非实验性实现是可能的,实施者应发布任何他们能证明符合规范的CR级特性的无前缀实现。

为了建立和维护CSS在不同实现之间的互操作性,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。2023 年 2 月 17 日。WD。URL:https://www.w3.org/TR/css-align-3/
[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]
CSS 间隙装饰模块级别 1。编辑草案。URL:https://drafts.csswg.org/css-gaps-1/
[CSS-GRID-1]
Tab Atkins Jr.;等。 CSS 网格布局模块级别 1。2020 年 12 月 18 日。CRD。URL:https://www.w3.org/TR/css-grid-1/
[CSS-GRID-2]
Tab Atkins Jr.;Elika Etemad;Rossen Atanassov。 CSS 网格布局模块级别 2。2020 年 12 月 18 日。CRD。URL:https://www.w3.org/TR/css-grid-2/
[CSS-GRID-3]
Tab Atkins Jr.;等。 CSS 网格布局模块级别 3。2024 年 10 月 3 日。WD。URL:https://www.w3.org/TR/css-grid-3/
[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/CSS21/
[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 弹性容器、网格容器、瀑布流容器 不适用 离散 按语法 如指定
item-direction auto | row | column | row-reverse | column-reverse auto 弹性容器、网格容器、瀑布流容器 不适用 离散 按语法 如指定
item-flow <'item-direction'> || <'item-wrap'> || <'item-pack'> || <'item-slack'> 参见各个属性 参见各个属性 参见各个属性 参见各个属性 参见各个属性 按语法 参见各个属性
item-pack normal | dense || balance normal 弹性容器、网格容器、瀑布流容器 不适用 离散 按语法 如指定
item-slack <length-percentage> | infinite 1em 瀑布流容器 相对于瀑布流容器的网格轴内容框大小 作为长度 按语法 计算后的 <length-percentage> 值
item-track auto | row | column | row-reverse | column-reverse auto 弹性容器、网格容器、瀑布流容器 不适用 离散 按语法 如指定
item-wrap [ auto | nowrap | wrap ] || [ normal | reverse ] | wrap-reverse auto 弹性容器、网格容器、瀑布流容器 不适用 离散 按语法 如指定

问题索引

或者,对于此处自动放置的项目,重新排序是否应该是默认行为?
问题(11593):我们仍在讨论使用何种语法开关来建立瀑布流布局。 目前的提案包括:
初始轨道列表应该是什么? [问题 #10869]
我们是否应该允许自动重复基于内容的轨道? 这对于它们来说是一个合理的定义吗? 它们是否也应该以某种方式在网格布局中工作? [问题 #10915]
目前尚不清楚我们是否真的需要这个值。 请注意,显式网格已经根据需要从 grid-auto-columns/grid-auto-rows/masonry-auto-tracks 中获取值, 以匹配模板区域的数量。 [问题 #10854]
需要一个更好的例子!!!
1em 是正确的默认值吗?
这是否也应该更新放置光标?
堆叠轴中的对齐方式是否应该做一些更复杂的事情? 那应该是什么?
我们可以支持第一行的基线对齐。我们想要这样做吗?
最后一条基线是否应该来自最后放置的最低项目?
堆叠轴中定义静态位置可能很有用。 也许它可以定义为该点网格轴轨道的最大(或最小?)当前运行位置?或者是它前面项目的末尾?
此部分可能会移至其他规范, 例如 [css-display-4], 因为它影响多种显示类型。
CSSWG 仍在研究这些属性应如何命名以及如何组合在一起。 [问题 #11480]
关于此属性有两个悬而未决的争论: a) 它应该叫什么名字以及 b) 它描述的是主要放置方向, 还是放置项目的轨道的方向; 换句话说,此属性定义的主轴主放置轴还是主轨道轴。 这些对于弹性布局网格布局是相同的, 但对于瀑布流布局则不同,其主要放置方向 是横跨其轨道。 [问题 #11480]
此属性的解释和命名取决于 item-direction/item-track 的轴的解释。 [问题 #11480]
切换到瀑布流布局的提案之一是向此 item-pack 属性添加一个 collapse 值。 [问题 #11243]
dense 打包是否应适用于瀑布流? 在瀑布流中,这要昂贵得多, 因为您必须在每个可能的间隙位置布置元素, 以查看它是否足够短以适合; 而网格只需处理一些整数即可。 [问题 #9326]