1. 引言
本节不具备规范性。
网格布局是一种 CSS 的布局模型,具有强大的控制盒子及其内容的尺寸和定位的能力。 网格布局专为二维布局优化:即在两个方向都需要内容对齐的布局场景。
虽然许多布局可以通过常规网格布局表达, 但在两个轴上将项目限制在网格中,也会导致无法表达 Web 上一些常见布局。
本模块定义了一种网格布局变体,移除了该限制, 使得项目可在一个轴上放入类似网格的轨道, 而在另一个轴上顺序堆叠。 未被明确放入特定轨道的项目, 会根据当前已放置项目的布局尺寸, 被放到剩余空间最多的列(或行)中。
1.1. 背景与动机
1.1.1. 瀑布流布局与自动放置项目
网格车道布局, 有时也称为“瀑布流布局”或“masonry 布局”, 是一种常见的 Web 设计模式,其中多个项目(通常是图片或短文摘要) 被逐个放入列中, 排列方式类似于砖石结构建造。 不同于多列布局和多行列弹性布局, 在这些布局中,内容会在第一列从上向下排布 直到溢出到第二列, 自动放置在网格车道布局里为每个新项目选择列, 保证新项目一般位于比后放置项更靠上的位置。
这里,每个项目高度都不同 (取决于内容和列宽), 检查 DOM 可看到 (视觉内容本身无法体现顺序) 每个项目都被放入当前高度最小的那一列。
这种布局表面上与多列布局相似; 但它的优点在于,向下滚动页面时, 布局中的“后面”项目 (如在搜索结果中相关度较低的项目) 会更自然地出现在下方。
无法用早期的 CSS 布局模型实现此布局, 除非事先已知每个项目的高度, 或用 JavaScript 进行内容测量和放置。
使用display: grid-lanes配合grid-template-columns 就可以实现这种网格车道布局
1.1.2. 一维网格布局
网格布局 支持强大的轨道尺寸与双轴显式放置, 但有时布局仅需在一个维度上对齐项目。
将网格车道布局 与显式定位项目结合使用, 可实现这种一维网格布局。
1.2. 属性值定义
本规范遵循CSS 属性定义约定,引用自[CSS2], 并采用属性值定义语法(见[CSS-VALUES-3])。 本规范未定义的值类型在 CSS 属性值与单位[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 属性有助于减少因自动放置项目时 堆叠轴上的微小尺寸差异所产生的回溯感。 但当自动放置与显式放置或跨区项目混合时, 还是可能发生一定程度的“回溯”现象。
< 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 { display : grid - lanes ; grid-template-columns : repeat ( 5 , auto ); } . item { height : 50 px ; } . item . wide { grid-column : span 3 ; } . item . tall { height : 90 px ; } </ style >
作者应了解这种情况 并尽量设计能减少“回溯”的布局, 便于聚焦和正确阅读顺序的把握。 或者,如若这些项目之间没有本质的顺序, 可用reading-flow属性让UA根据阅读和线性导航重排项目。
-
为item-tolerance选择合适的值, 即数值应足够大,避免对相近尺寸轨道的无谓区分, 但又不能大到忽略了真实的尺寸差异。
-
用显式放置方式将相关项目分组, 而不是打乱原有项目序。
与网格布局 和弹性布局一致, 作者也可以使用order 属性重排序; 但注意事项也同样适用。 参见CSS Grid Layout 2 § 4 重排序与无障碍性 以及CSS Display 4 § 3.1 重排序与无障碍性。
2.2. 建立网格车道布局
| 名称: | display |
|---|---|
| 新值: | grid-lanes | inline-grid-lanes |
- grid-lanes
- 此值会令元素生成 块级 网格车道容器盒。
- inline-grid-lanes
- 此值会令元素生成内联级 网格车道容器盒。
未在网格轴上作为子网格的网格车道容器会为其内容建立独立格式化上下文。
2.3. 网格轨道布局方向
网格轨道容器的方向, 即其网格轴是 内联轴(建立列) 还是块轴(建立行), 由 待定 属性决定。
该属性的初始值是normal, 它根据grid-template-*属性确定方向:
-
如果grid-template-columns为none 且grid-template-rows不为none, 则网格容器的块轴是网格轴 (建立行)。
.container {
display: grid-lanes;
grid-template-columns: 100px 200px;
}
而下列代码将创建一个横向增长的2行(“砖墙样式”)网格轨道容器:
.container {
display: grid-lanes;
grid-template-rows: 100px 200px;
}
需要确定此处是否复用grid-auto-flow (以及其值的含义), 还是定义一个新的属性如grid-lanes-direction。[Issue #12803]
3. 网格车道轨道规范
然而, 自动放置的子项会对所有轨道的尺寸产生贡献, 而不仅仅是对子项最终放置的那个轨道; 参见§ 3.4 网格轴轨道尺寸计算。
注意:这是因为自动放置的子项必须在布局时即时安排位置, 这样每个轨道才能知道自己“有多满” (从而决定下一个自动放置的子项应进入哪个轨道); 因此,轨道本身在布局时必须已经有明确的尺寸, 这样子项才知道它们的可用空间。
3.1. 声明网格车道轨道模板:grid-template-* 属性
grid-template-* 和 grid-auto-rows/grid-auto-columns 属性 (以及它们的简写) 应用于 网格轨道容器 的 网格轴, 并像普通 网格容器 一样建立轨道。 (在 堆叠轴 上会被忽略。)
3.1.1. 内在轨道与 repeat()
Level 3 扩展了 repeat() 表示法,允许重复时 最小轨道尺寸函数和 最大轨道尺寸函数都不是 确定值; 换言之,<auto-repeat> 的语法放宽如下:
<auto-repeat> = repeat( [ auto-fill | auto-fit ] , [ <line-names>? <track-size> ]+ <line-names>? )
为了解决重复次数, 需为此类轨道计算一个假设尺寸, 按CSS Grid Layout 2 § 12.4 初始化轨道尺寸和 CSS Grid Layout 2 § 12.5 解析内在轨道尺寸初始化轨道尺寸和解析内在轨道尺寸, 并以§ 3.4 网格轴轨道尺寸的假定作为依据:
-
忽略显式项目放置。 (即假设所有项目都为 自动位置。)
-
不要合并任何轨道。
-
将重复轨道列表扩展到可承载所有自动放置项目的程度, 即轨道列表应重复
2 + (最大跨度 - 2)/(repeat()中的轨道数)次, 并向下取整。
在repeat()列表中每个轨道的假设尺寸, 由该条目(按索引)对应的所有轨道中的最大值给出。
这种做法要在常规网格布局中也支持吗,还是回退到单次重复?如需支持,方法如何?[Issue #10915]
注: 这种简化的布局启发式定义是为“足够好”, 且保持快速和一致性。 忽略放置是为了让概念可执行; 你在不知道所需重复次数前, 无法确定某项目实际会落入哪个轨道 (即便其声明有确定放置)。
技术上,如果你的显式放置并不跨越或覆盖重复片段, 我们实际上是能知道放置的。 是否希望上述算法调整支持这种情景? 即对于 auto repeat(auto-fill, ...) auto, 如果显式放置在 line 1 或 -1, 可以只影响对应轨道 (而不假定会出现在每个轨道)。
3.2. 子网格
子网格化允许嵌套的网格轨道容器(以及网格容器) 共享轨道尺寸。 如果父元素对应的轴是网格轴, 则子网格的该轴从父容器继承 如网格容器具体规范所述; 如果父元素对应的轴是堆叠轴, 子网格的该轴也充当堆叠轴。
在网格车道布局中, 自动放置的子网格 不会从父网格继承任何线名, 因为那样会使项目放置依赖于布局结果; 但子网格的轨道仍照常与父网格轨道对齐。
<style> .grid{ display : inline-grid-lanes; grid-template-rows : auto auto100 px ; align-content : center; height : 300 px ; border : 1 px solid; } .grid > *{ margin : 5 px ; background : silver; } .grid > :nth-child( 2 n ) { background : pink; } .grid subgrid{ display : grid; grid : subgrid / subgrid; grid-row : 2 / span2 ; grid-gap : 30 px ; } .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()表示法引入了新关键字以及特有的 grid-lanes 行为。
3.3.1. repeat(auto-fit)
在 网格轨道容器(如同普通 网格容器) 中,auto-fit 的行为类似于 auto-fill, 但空轨道会被 折叠。 但是,由于放置发生在轨道尺寸确定之后, 网格轨道容器会采用启发式方法 判断某个轨道是否会被占用:
-
所有被显式放置的轨道都视为已占用。
-
所有自动放置项目的跨度和为N,则前N个未占用轨道都视为已占用。
所有通过auto-fit生成且被此启发判定为未占用的轨道, 均视为“空的”并被折叠。 折叠网格轨道无法用于放置自动项目。
注:在使用auto-fill时,自动放置项有可能被放入某个轨道,但如果使用auto-fit则该轨道会被折叠,特别是在存在跨度大于1的自动放置项,且与显式放置项目混用时,显式放置后留下的空隙太小,无法容纳自动放置项的情况下。
3.4. 网格轴轨道尺寸
轨道尺寸算法与CSS Grid相同, 不同之处在于确定哪些项目贡献内在尺寸时:
-
所有被显式放入该轨道的项目都贡献,且
-
所有自动网格位置的项目都贡献 (无论最终是否放入该轨道)。
对于跨度项目且拥有自动网格位置的情况, 视为在每个可起始位置都放了一份, 逐个计算贡献。
-
在网格线1,从前两列各贡献110px。
-
在网格线2,为第二列贡献120px。
-
在网格线3,为第四列贡献120px。
-
在网格线4,为第4、5列各贡献110px。
注意:该算法确保每个轨道至少足够大, 可以容纳最终放置在其中的所有子项, 且不会在放置和轨道尺寸计算之间产生依赖循环。 但根据尺寸的差异, 轨道可能会比实际需要的大: 只有在所有子项都明确放置在网格轴上, 或所有子项尺寸相同 (或在跨行/跨列时为该尺寸的等倍)时才能保证轨道与内容完全契合。
3.4.1. 子网格项目尺寸贡献
当为普通网格容器 或网格轨道容器的轨道进行尺寸计算时, 网格轨道子网格会对具有自动网格位置的子项进行特殊处理:
-
此类项目会放置进子网格可跨越的每个网格轨道。 (若子网格有确定位置,则只放跨越轨道; 若有自动位置,则在父网格所有轨道。)
-
此类项目获得它可被虚放的每个边缘的最大 margin/border/padding 贡献。 若跨越整个子网格,四边都取。 (见CSS Grid Layout §9)
3.4.2. 优化轨道尺寸
可将具有相同跨度和放置的项目聚合为单个虚拟项,优化轨道尺寸,方法如下:
-
按下列属性将所有网格项目分为项目组:
-
项目跨度
-
项目放置位置 (即允许放在哪些轨道)
-
项目的基线分组
注: 如跨度为2且定位于第二轨的项目,与跨度为2且自动位置的项目是不同组。
-
-
为每个项目组合成一个虚拟网格项,
其内在尺寸贡献是组内所有项的最大值。
若这些项用基线对齐, 则把所有项都放入假想轨道, 得到共享基线及 shim, 相应调整该组内在尺寸贡献。
- 将每个虚拟网格项的假设副本, 放入网格轴的每一个该项有可能占据的位置的轨道中, 并用这些子项运行轨道尺寸计算算法。 得到的轨道尺寸就是网格轨道容器的轨道尺寸。
注: 如与上文轨道尺寸算法结果不符, 则是错误, 请向 CSSWG 报告。
4. 网格轨道子项放置
在网格轴上, 子项可以使用常见的网格放置属性的语法显式放置到轨道中并跨越轨道。 自动放置则采用§ 4.4 网格轨道布局与放置算法, 将每个具有自动网格位置的子项 放入当前可用的“最短”轨道中。
.container{ grid-template-columns : repeat ( 3 , auto); } .container > :nth-child( 2 ) { /* auto-placed, but spanning. */ grid-column: span2 ; } .container > :nth-child( 3 ) { /* manually placed */ grid-column:3 ; } /* all other children are auto-placed */
4.1. 指定网格轴项目放置:grid-column-* 和 grid-row-* 属性
grid-column-* 和 grid-row-* 属性 (包括速记) 适用于项目的网格轴, 并如常规网格布局一般完成放置。
4.2. 放置精度:item-tolerance 属性
| 名称: | item-tolerance |
|---|---|
| 值: | normal | <length-percentage> | infinite |
| 初始值: | normal |
| 适用对象: | 网格轨道容器 |
| 可继承: | 否 |
| 百分比: | 相对于网格轴 内容框尺寸的网格轨道容器 |
| 计算值: | a computed <length-percentage> value |
| 规范序顺: | 按语法 |
| 动画类型: | 按长度 |
网格轨道容器通过将每个网格子项 放入当前填充最少的网格轨道来完成填充。 当有多个轨道同为“最少填充”时, 按顺序放置子项会呈现较好效果。 但如果轨道只是非常轻微高度不同, 让子项不按顺序填满会显得奇怪, 因为高度的差异并不会被有意义地感知出来。
item-tolerance属性用于指定认为轨道“同高”的阈值, 以决定这些轨道会按顺序填充。
- <length-percentage>
-
为网格轨道容器指定并列阈值。 当放置位置与最短位置距离在该值以内时, 这些位置被视为“同样好”(“并列”)。
注意:初始值为“较小”距离(1em), 这个值很适合表示“足够接近”。
- normal
- infinite
-
指定无限 并列阈值。 这样会让子项严格按顺序分布, 完全不考虑轨道长度。
注意:该值可能导致连续子项 在堆叠轴上的位置 相差很大,可能让读者困惑。 如果初始值(`1em`)太小, 可考虑用更大值(如`10em`或`50vh`)代替`infinite`。
若采用默认容差1em, 第一、第四列都被视为“并列”, 因此会优先选择第一列。
如果把容差设为0px, 就不存在“并列”, 只有第四列会被选做放置点。
CSSWG欢迎对该属性提出更好的命名建议。[问题 #10884]
注意:我们预计未来把此属性也应用于弹性布局, 参阅相关讨论 了解可能应用方式。
4.3. 密集放置:dense 关键字
在 网格布局中,grid-auto-flow: dense 允许在 网格子项放置算法 过程中回溯。dense 关键字同样允许 在 网格轨道放置算法 中回溯。 但由于在 网格轨道布局中,子项放置与尺寸计算紧密耦合, 只有当空槽的所有轨道的实际尺寸 与子项正常放置时的轨道尺寸一致时, 某个子项才能回溯到该空槽。
注意:这种限制可以避免对子项进行多次布局。
4.4. 网格车道布局与放置算法
对于 网格轴 中的每个轨道, 保持一个初始化为零的累计位置。 还要维护一个自动放置光标, 初始指向第一条线。
对于顺序调整后的文档顺序中的每个子项:
-
如果该项在网格轴上有一个确定的网格位置,
就采用该位置。
否则,按照如下子步骤处理其网格轴放置:
- 将该项放置在其 网格轴 轨道上, 位于所跨轨道的 累计位置 的最大值处
-
计算该项的包含块的尺寸,然后进行布局。
并把其所跨累计位置的网格轴轨道
设置为
max_pos + 外部尺寸 + grid-gap。此处盒子的外部尺寸会被限定为不小于零。
注意: 即如果盒子有足够大的负外边距, 在这里不会计为负尺寸。 轨道的累计位置不会减少, 所以负尺寸盒子不会导致此轨道后续正常尺寸子项重叠到已有的子项上。
-
如果网格轨道容器采用dense方式布局,
且布局中存在(如因跨轨道子项等)跳过的空位,
且该项以现有尺寸如果早先放置可以适配这些空位,
并且实际放置所跨轨道的总已用尺寸与这些空位所跨轨道的总已用尺寸一致,
则将该项放到高度最高的空位那里。
若多个合格空位距最高值在并列阈值范围内,
就选靠起始端的那个。
然后将自动放置光标和累计位置
回退到本项放置前的值。
注意: 那些视觉上“侵入”前方空隙的子项 (通过负外边距、position: relative、变换等方式), 不会影响这些空隙的尺寸。 后面的子项依然会放进这些空隙,并在视觉上和前边子项重叠。
注意: 密集填充回填时会忽略自动放置光标, 且回填后不会更新光标。 如果没有合适的空位回填, 就和未指定dense时行为完全一致。
注意:该算法会选择让子项尽可能高位放置的轨道。 若有并列,则优选最早的轨道, 尽可能在上次放置点之后 (确保就算有并列也始终“向前推进”)。
4.4.1. 包含块
参与网格轨道布局的网格子项的包含块,由其在网格轴上的网格区域和网格容器在堆叠轴上的内容框共同组成。
4.4.2. 放置与书写模式
注意:与所有网格布局一样, 网格轨道布局及放置也会受到书写模式的影响。 例如,对于direction: rtl, 无论内联轴是网格轴还是堆叠轴,子项都将从右向左放置,而不是从左向右。
<style> .grid{ display : inline-grid-lanes; direction : rtl; grid-template-columns : repeat ( 4 , 2 ch ); border : 1 px solid; } item{ background : silver} item:nth-child( 2 n +1 ) { background : pink; height : 4 em ; } </style>
< div class = "grid" > < item > 1</ item > < item style = "grid-column:span 2" > 2</ item > < item > 3</ item > < item > 4</ item > </ div >
<style> .grid{ display : inline-grid-lanes; direction : rtl; width : 10 ch ; column-gap : 1 ch ; grid-template-rows : repeat ( 4 , 2 em ); border : 1 px solid; } item{ background : silver} item:nth-child( 2 n +1 ) { background : pink; width : 4 ch ; } </style>
< div class = "grid" > < item > 1</ item > < item style = "grid-row:span 2" > 2</ item > < item > 3</ item > < item > 4</ item > </ div >
5. 网格容器定尺寸
网格容器尺寸计算的规则与普通网格容器相同, 但对堆叠轴有如下替换方式: 堆叠轴上,一个网格容器的 max-content 尺寸(min-content 尺寸), 当 网格轨道容器 在该轴以 max-content 约束(min-content 约束)被计算时, 就等于堆叠区间的尺寸。 堆叠区间 指每个轨道第一个子项的起始外侧边界中最靠起始端的位置 到每个轨道最后一个子项的终止外侧边界中最靠末端的位置的范围。
<style> .grid{ display : inline-grid-lanes; grid-template-columns : 50 px 100 px auto; grid-gap : 10 px ; border : 1 px solid; } item{ background : silver; margin : 5 px ; } </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. 对齐与间距
6.1. 间隙:row-gap、 column-gap,以及 gap 属性
间隙(Gutters)在两个轴向均可用 ,通过 row-gap 与 column-gap 属性(以及它们的 gap 缩写)实现。 在 网格轴中的表现与普通 网格容器一致; 参见 CSS Grid Layout 2 § 11. 对齐与间距。 在 堆叠轴中, 间隙应用于每对相邻子项的 margin box 之间。 任一轴上的外边距不会折叠。
6.2. 网格轴对齐:align-content/justify-content,align-self/justify-self,以及 align-items/justify-items 属性
在 网格轴上, 盒子对齐属性 的表现与普通 网格容器一致。 参见CSS Grid Layout 2 § 11. 对齐与间距 和 CSS Box Alignment Level 3。
6.3. 堆叠轴内容分布:align-content/justify-content 属性
在 堆叠轴上, 内容分布针对整体内容生效,表现类似于块容器的行为。 更具体地说,对齐主体为堆叠区间。
注意:在 堆叠轴 中,这些属性始终只有一个对齐主体, 所以唯一的align-content / justify-content值只会出现 start、 center、 end, 以及 基线对齐。 (normal 和 stretch 的行为与 start 完全一致, 分布对齐值与其回退对齐表现一致。) 如果网格子项在堆叠轴 溢出网格容器的内容框, 那么 堆叠区间 就会大于 网格容器的 内容框。
6.4. 堆叠轴自身对齐:align-self/justify-self 和 align-items/justify-items 属性
在 堆叠轴, 自身对齐属性只对紧邻布局空隙的子项生效, 即那些在网格轨道内,正好紧靠一个跨轴项前或作为最后一个子项放置的元素。 对齐主体为该项的margin box, 对齐容器为该盒加相邻空隙。
这种自身对齐属性的堆叠轴定义合理吗?[Issue #10275]
6.5. 基线对齐
子项在 基线对齐下在 网格轴轨道内表现与普通 网格容器一致, 而 网格容器在该轴的基线确定方式也与普通 网格容器一致。
基线对齐不支持于 堆叠轴。 此轴中 网格容器的第一基线集 从每个轨道第一个子项里最高的对齐基线生成, 最后基线集从每个轨道最后一个子项中最低的 对齐基线 生成。
7. 分片(分页)
7.1. 堆叠轴内的分片
每个 网格轴 轨道在 堆叠轴 内独立分片。 若某个 网格子项 被分片, 或其前后有 强制断点, 那么其所跨轨道的 累计位置会被设置为对应 网格轴 的 分片容器的尺寸,这样这些轨道内不会再被放置额外子项。 被分割成多个片段的项在 网格轴 中所有片段位置都一致。 被推送到下一分片的网格子项将在下一个 网格容器片段再次放置。 放置流程会持续,直到所有项都被放置或推送到新分片里为止。
7.2. 网格轴内的分片
网格轴上的网格轨道容器同样支持分片。 此时分片的行为更像普通 网格容器 的分片; 不过,在分片发生前仍有个独立的步骤确定每个子项应放在哪条 网格轴 轨道上。
8. 绝对定位
与网格对齐的绝对定位后代在网格轨道容器中与普通网格容器一样受支持; 但在堆叠轴,只存在两条(以及auto线)用于放置:
也许可以在堆叠轴定义一个静态位置。 例如可以用当前累计位置的max(或min?),或前一项的结尾?
9. 优雅降级
通常,网格轨道设计在支持网格布局但不支持网格轨道布局的UA中也能较好降级。
这里有一个例子说明这种情况。
display : grid; display : grid-lanes; /* 不支持网格轨道布局的UA会忽略此行 */ grid-template-columns:150 px 100 px 50 px ;
这会创建三列布局, 但如果UA不支持网格轨道布局, 块轴中会出现“更多空隙”。 下图展示了支持网格轨道的UA渲染效果:
附录A:通用布局子项流控:item-*系列属性
此章节可能会移到其它规范, 比如[css-display-4], 因为它影响多种布局类型。 当前还在讨论是否保留该想法。
CSS中多种布局模式都会将子元素 作为原子“子项”组织为行和/或列, 并允许作者配置排序与放置。 item-*系列属性提供了这些排序与放置选项的通用控制, 封装了布局专有的flex-flow与grid-auto-flow属性。
| 按流向提案 | 按轨道提案 | 值空间 | 描述 | 原flex属性 | 原grid属性 |
|---|---|---|---|---|---|
| item-direction | item-track | auto | row | column | row-reverse | column-reverse | 控制子项按行or列排列, 及其顺序按始端到末端,还是反向。 | flex-direction | grid-auto-flow |
| item-wrap | item-cross | [ auto | nowrap | wrap ] || [ normal | reverse ] | wrap-reverse | 控制子项在与row/column属性正交的轴上是否换行, 以及换行方向。 | flex-wrap | 本级别引入到grid-auto-flow。 |
| item-pack | item-pack | normal | dense || balance | 配置子项如何填充其轨道。 | grid-auto-flow | |
| item-tolerance | item-tolerance | normal | <length-percentage> | infinite | 定义布局过程中容许的“松弛”量。 |
CSSWG仍在完善这些属性的命名与组织。[问题 #11480]
子项主轴:item-track/item-direction
| 名称: | item-direction, item-track |
|---|---|
| 值: | auto | row | column | row-reverse | column-reverse |
| 初始值: | auto |
| 适用对象: | 弹性容器, 网格容器, 网格轨道容器 |
| 可继承: | 否 |
| 百分比: | N/A |
| 计算值: | 按声明 |
| 规范序顺: | 按语法 |
| 动画类型: | 离散型 |
该属性控制子项是按行还是按列排列,并决定轨道内顺序是始端到末端还是反过来。
此属性有两个悬而未决的问题: a)命名是否合适; b)它描述的是放置的主方向,还是轨道的朝向; 换句话说,此属性定义的主轴 到底是主放置轴 还是主轨道轴。 对于弹性布局和网格布局,它们二者一致, 但网格轨道布局中两者不一样。 参见讨论。[问题 #11480]
- auto
-
-
在网格轨道容器 上,如果grid-template-rows不为none 且grid-template-columns为none, 计算为行轨道,否则计算为列轨道。
- 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
- normal
-
子项在与主轨道轴正交方向按始端到末端顺序放置。
在弹性布局和网格布局中, 这控制新轨道(弹性行或网格轨道)插入的方向。
在网格轨道布局中, 针对轨道语法这是在高度相同时选哪条轨道; 针对流语法则决定子项在其轨道的填充方向。
- reverse
-
子项在与主轨道轴正交方向按末端到始端顺序放置。
- wrap-reverse
-
计算值为wrap reverse。
注意:该值是为兼容现有flex-wrap设置的。
该属性的解释与命名依赖于 item-direction/item-track轴定义。[问题 #11480]
子项排布方式:item-pack属性
| 名称: | item-pack |
|---|---|
| 值: | normal | dense || balance |
| 初始值: | normal |
| 适用对象: | 弹性容器, 网格容器, 网格轨道容器 |
| 可继承: | 否 |
| 百分比: | N/A |
| 计算值: | 按声明 |
| 规范序顺: | 按语法 |
| 动画类型: | 离散型 |
此属性以布局自有方式控制子项如何分配到轨道中。
- normal
-
采用布局模式的默认填充策略。
- dense
-
允许回溯,把子项放到此前跳过的空位。 (前项太大时会跳过空位)
例如, 在弹性布局可选用此前未用尽行的剩余空间。
- balance
-
在弹性布局下, 该值会平衡每行内容(包含最后一行), 类似text-wrap-style: balance。
子项排布简写:item-flow 简写
| 名称: | item-flow |
|---|---|
| 值: | <'item-direction'> || <'item-wrap'> || <'item-pack'> || <'item-tolerance'> |
| 初始值: | 见各属性 |
| 适用对象: | 见各属性 |
| 可继承: | 见各属性 |
| 百分比: | 见各属性 |
| 计算值: | 见各属性 |
| 动画类型: | 见各属性 |
| 规范序顺: | 按语法 |
10. 致谢
感谢 Cameron McCormack 编写了瀑布流布局说明文档(其中的背景章节被引用),并向 CSSWG 做了演示, 以及 Mats Palmgren 开发了本规范的最初版本。 还要感谢所有对该特性初始提案提供反馈的人。
11. 安全注意事项
作为布局规范, 本规范未引入除一般 CSS 布局外的任何新安全注意事项。
12. 隐私注意事项
作为布局规范, 本规范未引入除一般 CSS 布局外的任何新隐私注意事项。
变更
Level 2 以来的新增内容
自 Level 2 起新增了以下功能:
- 新增网格车道布局。
- 扩展了 repeat(auto-fill) 和 repeat(auto-fit),允许其接受不定轨道尺寸函数。 (Issue 9321, Issue 12899)
- 增加了item-flow属性及其长属性, 用于通用项目排序与放置控制。 参见附录A:通用布局项流控制:item-* 属性。 (Issue 11480)
最近变更
自 2025年9月17日工作草案以来进行了如下更改:
-
定义了一个新的内部 display 类型 grid-lanes, 用于建立网格车道布局, 并更新了规范用词以保持一致。 (Issue 12022)
-
从repeat()中移除了不必要的 auto-areas 值。 (Issue 10854)
-
调整了 repeat(auto-fill) 和 repeat(auto-fit) 在不定轨道尺寸函数下的启发式处理方式。 (Issue 12899)
-
将项目对轨道累计位置的贡献下限设为零。 (Issue 12918)
另见更早的变更。