CSS 网格布局模块第 1 级

W3C 候选推荐标准草案,

关于此文档的更多细节
此版本
https://w3org.cn/TR/2025/CRD-css-grid-1-20250326/
最新发布版本
https://w3org.cn/TR/css-grid-1/
编辑草案
https://drafts.csswg.org/css-grid-1/
历史
https://w3org.cn/standards/history/css-grid-1/
实现报告
https://wpt.fyi/results/css/css-grid
反馈
CSS 工作组问题仓库
意见处理说明
CSSWG GitHub
文档内联
编辑
Tab Atkins Jr. (Google)
Elika J. Etemad / fantasai (Apple)
(Microsoft)
(Igalia)
前任编辑
(Microsoft Corporation)
(Microsoft Corporation)
建议编辑此规范
GitHub 编辑器
测试套件
https://wpt.fyi/results/css/css-grid/

摘要

本 CSS 模块定义了一个二维网格布局系统,专为用户界面设计而优化。在网格布局模型中,网格容器的子元素可以被定位到预定义的灵活或固定尺寸的布局网格中的任意槽位。

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

关于本文档

本节描述了本文档发布时的状态。当前的 W3C 出版物列表以及本技术报告的最新修订版,可在 W3C 标准和草案索引(https://w3org.cn/TR/)中找到。

本文档由 CSS 工作组候选推荐标准草案的形式发布,遵循 推荐标准轨道。作为候选推荐标准发布并不意味着 W3C 及其成员的认可。候选推荐标准草案整合了前一个候选推荐标准中的变更,工作组打算将其包含在随后的候选推荐标准快照中。

这是一份草案文档,可能会随时被其他文档更新、替换或废弃。将其作为非进行中工作引用是不恰当的。

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

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

本文档由在一个受 W3C 专利政策约束下运作的团体编写。W3C 维护着一份与该团体交付成果相关的专利披露公开列表;该页面还包含了披露专利的说明。任何知晓其认为包含 必要权利要求 (Essential Claim(s)) 的个人,必须根据 W3C 专利政策第 6 节披露相关信息。

以下功能存在风险,可能会在 CR 期间被删除:

“风险(At-risk)”是 W3C 流程中的术语,并不一定意味着该特性面临被删除或推迟的危险。这表示工作组认为该特性可能难以及时实现互操作,将其标记为此类允许工作组在转向“建议推荐标准(Proposed Rec)”阶段时,在必要的情况下删除该特性,而无需先发布一个不包含该特性的新“候选推荐标准(Candidate Rec)”。

如果您注意到本网格布局模块与 弹性盒布局模块 (Flexible Box Layout Module) 之间存在任何不一致之处,请向 CSSWG 反馈,因为这很可能是一个错误。

1. 简介

本节不具有规范性。

网格布局 (Grid Layout) 是一种新的 CSS 布局模型,具有控制盒模型及其内容尺寸和定位的强大能力。与面向单轴的 弹性盒布局 (Flexible Box Layout) 不同,网格布局针对二维布局进行了优化:即在两个维度上都需要内容对齐的布局。

An example of flex layout:
		     two rows of items,
		     the first being three items a third of the space each,
		     and the second being five items, a fifth of the space each.
		     There is therefore alignment along the “rows”, but not along the “columns”.
代表性弹性布局示例
An example of grid layout:
		     two rows of items,
		     the first being four items—the last of which spans both rows,
		     and the second being two items—the first of which spans the first two columns— plus the spanned item from the first row.
代表性网格布局示例

此外,由于其能够在网格中显式定位项目,网格布局允许在不更改相应标记的情况下实现视觉布局结构的巨大转变。通过将 媒体查询 (Media Queries) 与控制网格容器及其子元素布局的 CSS 属性相结合,作者可以使其布局适应设备外形、方向和可用空间的变化,同时在不同展示环境下保持内容更理想的语义结构。

尽管许多布局既可以用网格也可以用 Flexbox 表示,但它们各有专长。网格强制执行二维对齐,采用自上而下的布局方法,允许项目的显式重叠,并具有更强大的跨度功能。Flexbox 专注于轴内的空间分配,采用更简单的自下而上的布局方法,可以使用基于内容尺寸的换行系统来控制其辅助轴,并依赖底层的标记层次结构来构建更复杂的布局。预计两者都将成为 CSS 作者宝贵且互补的工具。

1.1. 背景与动机

Image: Application layout example requiring horizontal and vertical alignment.
需要水平和垂直对齐的应用程序布局示例。

随着网站从简单的文档演变为复杂的交互式应用程序,文档布局技术(例如浮动)并不一定适合应用程序布局。通过使用表格、JavaScript 的组合,或对浮动元素进行精确测量,作者发现了实现所需布局的变通方法。适应可用空间的布局通常很脆弱,且在空间受限时会导致反直觉的行为。作为替代方案,许多 Web 应用程序的作者选择了固定布局,但无法利用屏幕上可用渲染空间的变化。

网格布局的功能解决了这些问题。它为作者提供了一种机制,通过一组可预测的尺寸调整行为将用于布局的可用空间划分为列和行。然后,作者可以将应用程序的构建块元素精确地定位和调整到由这些列和行相交定义的 网格区域 (grid areas) 中。以下示例说明了网格布局的自适应能力,以及它如何实现内容与样式的更清晰分离。

1.1.1. 使布局适应可用空间

Let us consider the layout of a game in two columns and three rows: the game title in the top left corner, the menu below it, and the score in the bottom left with the game board occupying the top and middle cells on the right followed by game controls filling the bottom left. The left column is sized to exactly fit its contents (the game title, menu items, and score), with the right column filling the remaining space.
五个网格项目根据内容尺寸和可用空间排列。
As more space becomes available in larger screens, the middle row / right column are allowed to expand to fill that space.
由于可用空间增加导致的网格增长。

网格布局可用于智能地调整网页内的元素尺寸。相邻的图形代表了一个布局中有五个主要组件的游戏:游戏标题、统计区域、游戏面板、分数区域和控制区域。作者的意图是划分游戏空间,使得

以下网格布局示例展示了作者如何以声明方式实现所有尺寸、放置和对齐规则。

/**
 * Define the space for each grid item by declaring the grid
 * on the grid container.
 */
#grid {
  /**
   * Two columns:
   *  1. the first sized to content,
   *  2. the second receives the remaining space
   *     (but is never smaller than the minimum size of the board
   *     or the game controls, which occupy this column [Figure 4])
   *
   * Three rows:
   *  3. the first sized to content,
   *  4. the middle row receives the remaining space
   *     (but is never smaller than the minimum height
   *      of the board or stats areas)
   *  5. the last sized to content.
   */
  display: grid;
  grid-template-columns:
    /* 1 */ auto
    /* 2 */ 1fr;
  grid-template-rows:
    /* 3 */ auto
    /* 4 */ 1fr
    /* 5 */ auto;
}

/* Specify the position of each grid item using coordinates on
 * the 'grid-row' and 'grid-column' properties of each grid item.
 */
#title    { grid-column: 1; grid-row: 1; }
#score    { grid-column: 1; grid-row: 3; }
#stats    { grid-column: 1; grid-row: 2; align-self: start; }
#board    { grid-column: 2; grid-row: 1 / span 2; }
#controls { grid-column: 2; grid-row: 3; justify-self: center; }
<div id="grid">
  <div id="title">Game Title</div>
  <div id="score">Score</div>
  <div id="stats">Stats</div>
  <div id="board">Board</div>
  <div id="controls">Controls</div>
</div>

注意: 有多种方法可以指定网格的结构,以及定位和调整 网格项目 (grid items),每种方法都针对不同的场景进行了优化。

1.1.2. 与源码顺序无关性

Image: An arrangement suitable for portrait orientation.
适用于“纵向”方向的排列。
Image: An arrangement suitable for landscape orientation.
适用于“横向”方向的排列。

延续前面的示例,作者还希望游戏能够适应不同的设备。此外,游戏应在以纵向或横向查看时优化组件的放置(图 6 和图 7)。通过将网格布局与媒体查询相结合,作者能够使用相同的语义标记,但独立于其源码顺序重新排列元素布局,以在两个方向上实现所需的布局。

以下示例使用了网格布局命名 网格项目 (grid item) 将要占用的空间的能力。这使得作者能够避免在网格定义更改时重写 网格项目 的规则。

@media (orientation: portrait) {
  #grid {
    display: grid;

    /* The rows, columns and areas of the grid are defined visually
     * using the grid-template-areas property.  Each string is a row,
     * and each word an area.  The number of words in a string
     * determines the number of columns. Note the number of words
     * in each string must be identical. */
    grid-template-areas: "title stats"
                         "score stats"
                         "board board"
                         "ctrls ctrls";

    /* The way to size columns and rows can be assigned with the
     * grid-template-columns and grid-template-rows properties. */
    grid-template-columns: auto 1fr;
    grid-template-rows: auto auto 1fr auto;
  }
}

@media (orientation: landscape) {
  #grid {
    display: grid;

    /* Again the template property defines areas of the same name,
     * but this time positioned differently to better suit a
     * landscape orientation. */
    grid-template-areas: "title board"
                         "stats board"
                         "score ctrls";

    grid-template-columns: auto 1fr;
    grid-template-rows: auto 1fr auto;
  }
}

/* The grid-area property places a grid item into a named
 * area of the grid. */
#title    { grid-area: title }
#score    { grid-area: score }
#stats    { grid-area: stats }
#board    { grid-area: board }
#controls { grid-area: ctrls }
<div id="grid">
  <div id="title">Game Title</div>
  <div id="score">Score</div>
  <div id="stats">Stats</div>
  <div id="board">Board</div>
  <div id="controls">Controls</div>
</div>

注意: 网格布局的重排能力有意地仅影响视觉渲染,而保留基于源码顺序的语音顺序和导航。这允许作者操纵视觉呈现,同时保持源码顺序完整,并针对非 CSS 用户代理及语音和顺序导航等线性模型进行优化。

网格项目的放置和重排绝不能替代正确的源码排序,因为这会破坏文档的可访问性。

1.2. 值定义

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

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

2. 概述

本节不具有规范性。

网格布局通过使用 网格 (grid) 来控制其内容的布局:这是一组相交的水平和垂直线,为 网格容器 (grid container) 的内容创建了一个尺寸和定位坐标系。网格布局的功能包括:

网格容器 可以根据需要嵌套或与 弹性容器 (flex containers) 混合使用,以创建更复杂的布局。

2.1. 定义网格

网格轨道)既可以通过 显式网格 属性显式声明和设置尺寸,也可以在项目放置在 显式网格 之外时隐式创建。grid 简写及其子属性定义了网格的参数。§ 7 定义网格

以下是一些网格声明的示例

2.2. 放置项目

网格容器 的内容被组织成单独的 网格项目 (grid items)(类似于 弹性项目 (flex items)),然后分配给 网格 中的预定义 区域 (areas)。它们可以使用 网格放置属性 通过坐标显式放置,或使用 自动放置 (auto-placement) 隐式放置到空区域。§ 8 放置网格项目

以下是使用 grid-area 简写的网格放置声明示例
grid-area: a;          /* Place into named grid area “a”     */
grid-area: auto;       /* Auto-place into next empty area    */
grid-area: 2 / 4;      /* Place into row 2, column 4         */
grid-area: 1 / 3 / -1; /* Place into column 3, span all rows */
grid-area: header-start / sidebar-start / footer-end / sidebar-end;
                       /* Place using named lines            */

这些等同于以下 grid-row + grid-column 声明

grid-row: a;                         grid-column: a;
grid-row: auto;                      grid-column: auto;
grid-row: 2;                         grid-column: 4;
grid-row: 1 / -1;                    grid-column: 3;
grid-row: header-start / footer-end; grid-column: sidebar-start / sidebar-end;

它们可以进一步分解为 grid-row-start/grid-row-end/grid-column-start/grid-column-end 分解属性,例如:

grid-area: a;
/* Equivalent to grid-row-start: a; grid-column-start: a; grid-row-end: a; grid-column-end: a; */

grid-area: 1 / 3 / -1;
/* Equivalent to grid-row-start: 1; grid-column-start: 3; grid-row-end: -1; grid-column-end: auto; */

2.3. 设置网格尺寸

一旦 网格项目放置网格轨道(行和列)的尺寸将根据其内容尺寸和/或网格定义中指定的可用空间进行计算。

产生的已定尺寸网格根据 网格容器align-contentjustify-content 属性在 网格容器 内进行 对齐§ 10 对齐与间距

以下示例通过在所有列之间分配任何额外空间来对齐所有列,并在网格小于 100vh 时将其在 网格容器 中居中。
main {
  display: grid;
  grid: auto-flow auto / repeat(auto-fill, 5em);
  min-height: 100vh;
  justify-content: space-between;
  align-content: safe center;
}

最后,每个 网格项目 会根据其自身的 尺寸调整 [CSS2]对齐属性 [CSS-ALIGN-3],在其分配的 网格区域 内调整尺寸并对齐。

3. 网格布局概念与术语

网格布局 (grid layout) 中,网格容器 的内容是通过将其定位和对齐到一个 网格 中来布置的。网格 (grid) 是一组相交的水平和垂直 网格线 (grid lines),将 网格容器 的空间划分为 网格区域 (grid areas)网格项目 (grid items)(代表 网格容器 的内容)可以放置在这些区域中。有两组 网格线:一组定义沿 块轴 (block axis) 运行的 列 (columns),另一组定义沿 内联轴 (inline axis) 的正交集合,定义 行 (rows)[CSS3-WRITING-MODES]

Image: Grid Lines.
网格线:块轴上有三条,内联轴上有四条。

3.1. 网格线

网格线 (Grid lines)网格 的水平和垂直分割线。网格线 存在于列或行的任一侧。它们可以通过数值索引或作者指定的名称来引用。网格项目 引用 网格线 以使用 网格放置属性 确定其在 网格 中的位置。

以下两个示例都创建了三条列 网格线 和四条行 网格线

第一个示例演示了作者如何使用 网格线 编号来定位 网格项目

#grid {
  display: grid;
  grid-template-columns: 150px 1fr;
  grid-template-rows: 50px 1fr 50px;
}

#item1 { grid-column: 2;
         grid-row-start: 1; grid-row-end: 4; }

第二个示例使用了显式命名的 网格线

/* equivalent layout to the prior example, but using named lines */
#grid {
  display: grid;
  grid-template-columns: 150px [item1-start] 1fr [item1-end];
  grid-template-rows: [item1-start] 50px 1fr 50px [item1-end];
}

#item1 {
  grid-column: item1-start / item1-end;
  grid-row: item1-start / item1-end;
}

3.2. 网格轨道与单元格

网格轨道 (Grid track)网格列网格行 的通用术语——换句话说,它是两条相邻 网格线 之间的空间。每个 网格轨道 都分配有一个尺寸函数,该函数控制列或行可以增长的宽度或高度,从而决定其边界 网格线 的间距。相邻的 网格轨道 可以由 排水沟(间隔) 分隔,否则它们将紧密排列。

网格单元格 (Grid cell) 是网格行和网格列的交集。它是定位 网格项目 时可以引用的最小网格单元。

在以下示例中,有两列三行。第一列固定为 150px。第二列使用灵活尺寸,这是网格中未分配空间的函数,因此会随着 网格容器 宽度的变化而变化。如果 网格容器 的使用宽度为 200px,则第二列宽 50px。如果 网格容器 的使用宽度为 100px,则第二列宽 0px,放置在其中的任何内容都将溢出 网格容器
#grid {
  display: grid;
  grid-template-columns: 150px 1fr;  /* two columns */
  grid-template-rows: 50px 1fr 50px; /* three rows  */
}

3.3. 网格区域

网格区域 (Grid area) 是用于布置一个或多个 网格项目 的逻辑空间。网格区域 由一个或多个相邻的 网格单元格 组成。它由四条 网格线 绑定,每侧一条,并参与其相交的 网格轨道 的尺寸调整。网格区域 可以使用 网格容器grid-template-areas 属性显式命名,或通过其边界 网格线 隐式引用。网格项目 使用 网格放置属性 分配给 网格区域

/* using the template syntax */
#grid  {
  display: grid;
  grid-template-areas: ". a"
                       "b a"
                       ". a";
  grid-template-columns: 150px 1fr;
  grid-template-rows: 50px 1fr 50px;
  height: 100vh;
}

#item1 { grid-area: a }
#item2 { grid-area: b }
#item3 { grid-area: b }

/* Align items 2 and 3 at different points in the grid area "b".  */
/* By default, grid items are stretched to fit their grid area    */
/* and these items would layer one over the other. */
#item2 { align-self: start; }
#item3 { justify-self: end; align-self: end; }

网格项目网格区域 形成了其布置在内的包含块。放置在同一个 网格区域 中的 网格项目 不会直接影响彼此的布局。然而,间接地,占用具有 固有尺寸函数网格轨道网格项目 可能会影响该轨道的尺寸(从而影响其边界 网格线 的位置),这反过来又会影响另一个 网格项目 的位置或尺寸。

4. 重排与无障碍访问

网格布局赋予作者对文档进行重新排列的强大权力。然而,这些并不能替代正确的文档源码顺序。order 属性和 网格放置 不会 影响非视觉媒体(如 语音)中的排序。同样,在视觉上重新排列网格项目也不会影响顺序导航模式的默认遍历顺序(如循环遍历链接,请参阅例如 tabindex [HTML])。

作者 必须 仅将 order网格放置属性 用于内容的视觉重排,而非逻辑重排。使用这些特性进行逻辑重排的样式表是不符合规范的。

注意: 这是为了使非视觉媒体和非 CSS 用户代理(通常按线性呈现内容)能够依赖逻辑源码顺序,同时利用网格布局的放置和排序功能来定制视觉排列。(由于视觉感知是二维且非线性的,预期的视觉顺序并不总是等同于预期的阅读顺序。)

许多网页在标记中具有相似的形状,顶部有页眉,底部有页脚,中间有内容区域和一或两个额外列。通常,希望内容出现在页面源码中,位于额外列之前。然而,这使得许多常见设计(例如简单地将额外列放在左侧而内容区域放在右侧)难以实现。多年来,这以多种方式得到了解决,当存在两列额外列时,通常称为“圣杯布局 (Holy Grail Layout)”。网格布局使得此示例变得微不足道。例如,以以下页面代码和预期布局的草图为例
<!DOCTYPE html>
<header>...</header>
<main>...</main>
<nav>...</nav>
<aside>...</aside>
<footer>...</footer>
In this page the header is at the top and the footer at the bottom, but the main is in the center, flanked by the nav on the right and the aside on the left.

这种布局可以轻松地通过网格布局实现

body { display: grid;
       grid: "h h h"
             "a b c"
             "f f f";
       grid-template-columns: auto 1fr 20%; }
main    { grid-area: b; min-width: 12em;     }
nav     { grid-area: a; /* auto min-width */ }
aside   { grid-area: c; min-width: 12em;     }

作为额外的奖励,默认情况下列都将是 等高 的,且主要内容将根据需要尽可能宽以填满屏幕。此外,这还可以与媒体查询相结合,以在窄屏幕上切换到全垂直布局。

@media all and (max-width: 60em) {
  /* Too narrow to support three columns */
  body { display: block; }
}

为了在所有展示模式下保持作者预期的顺序,创作工具——包括 WYSIWYG 编辑器以及基于 Web 的创作辅助工具——必须重新排列基础文档源码,并且不得使用 order网格放置属性 来进行重排,除非作者已明确指出基础文档顺序(决定语音和导航顺序)应与视觉顺序 不同步

例如,工具可以提供网格项目的拖放排列,以及处理不同屏幕尺寸范围的替代布局的媒体查询。

由于在大多数情况下,重排应影响所有屏幕范围以及导航和语音顺序,工具将通过同时重排 DOM 层来匹配产生的拖放视觉排列。然而,在某些情况下,作者可能希望针对不同屏幕尺寸采用不同的视觉排列。工具可以通过结合使用 网格放置属性 和媒体查询来提供此功能,但同时也将最小屏幕尺寸的排列与基础 DOM 顺序绑定(因为这最有可能成为逻辑线性呈现顺序),而在其他尺寸范围中使用 网格放置属性 来重新排列视觉呈现。

此工具将是符合规范的,而仅使用 网格放置属性 来处理拖放网格重排的工具(无论实现起来多么方便)都将是不符合规范的。

5. 网格容器

5.1. 建立网格容器:gridinline-grid display

名称display
新值 grid | inline-grid
grid
此值会导致元素生成一个 网格容器 盒,当放置在 流式布局 (flow layout) 中时,它是 块级 (block-level) 的。
inline-grid
此值会导致元素生成一个 网格容器 盒,当放置在 流式布局 中时,它是 内联级 (inline-level) 的。

网格容器 (Grid container) 为其内容建立一个 独立的 网格格式化上下文 (grid formatting context)。这与建立独立的 块格式化上下文 相同,只是使用网格布局代替了块布局:浮动元素不会侵入网格容器,并且网格容器的外边距不会与其内容的外边距重叠。网格容器 的内容被布置到一个 网格 中,网格线 构成了每个 网格项目 的包含块边界。

网格容器不是块容器,因此一些设计假设基于块布局的属性在网格布局上下文中不适用。特别是:

如果元素的指定 displayinline-grid 且元素是浮动或绝对定位的,则 display 的计算值为 gridCSS 2.1 第 9.7 章 中的表格因此被修正,包含一个额外行,“指定值”列为 inline-grid,“计算值”列为 grid

5.2. 设置网格容器尺寸

注意:请参阅 [CSS-SIZING-3] 获取本节术语的定义。

网格容器 是根据其参与的格式化上下文的规则来设置尺寸的:

在内联和块格式化上下文中,网格容器auto 块尺寸 (block size) 是其 max-content 尺寸。

块布局规范可能应该定义这一点,但尚未编写。

网格容器max-content 尺寸min-content 尺寸)是当网格在 max-content 约束min-content 约束)下设置尺寸时,相应轴中 网格容器 的轨道尺寸(包括排水沟/间隔)的总和。

5.3. 可滚动网格溢出

overflow 属性适用于 网格容器

正如其包含在固有尺寸调整中一样(参见 § 5.2 设置网格容器尺寸),网格 也包含在 网格容器可滚动溢出区域 (scrollable overflow region) 中。

注意:网格容器滚动容器 (scroll container) 时,需注意与内边距的交互:定义额外的内边距应根据需要添加到 可滚动溢出矩形 (scrollable overflow rectangle) 中,以启用可滚动内容的 place-content: end 对齐。请参阅 CSS Overflow 3 § 2.2 可滚动溢出

5.4. 限制大型网格

由于内存有限,用户代理 (UA) 可能会将 隐式网格 的可能尺寸限制在用户代理定义的限制内(通常应涵盖 [-10000, 10000] 范围内的线),并丢弃该限制之外的所有线。如果一个网格项目被放置在此限制之外,其网格区域必须被 夹紧 (clamped) 到此受限网格内。

夹紧一个网格区域

例如,如果用户代理仅支持每个维度最多 1000 条轨道的网格,则以下放置属性
.grid-item {
  grid-row: 500 / 1500;
  grid-column: 2000 / 3000;
}

最终将等同于

.grid-item {
  grid-row: 500 / 1001;
  grid-column: 1000 / 1001;
}

6. 网格项目

粗略地说,网格容器网格项目 (grid items) 是代表其 流内 (in-flow) 内容的盒。

网格容器 的每个 流内 子元素都成为一个 网格项目,每个子 文本序列 都被包装在一个 匿名 (anonymous) 块容器 (block container) 网格项目 中。但是,如果 文本序列 仅包含 空白字符(即受 white-space 属性影响的字符),它反而不会被渲染(就像其 文本节点display:none 一样)。

网格项目示例

<div style="display: grid">

  <!-- grid item: block child -->
  <div id="item1">block</div>

  <!-- grid item: floated element; floating is ignored -->
  <div id="item2" style="float: left;">float</div>

  <!-- grid item: anonymous block box around inline content -->
  anonymous item 3

  <!-- grid item: inline child -->
  <span>
    item 4
    <!-- grid items do not split around blocks -->
    <q style="display: block" id=not-an-item>item 4</q>
    item 4
  </span>
</div>
从上述代码块确定的网格项目
  1. grid item containing block.
  2. grid item containing float.
  3. (Anonymous, unstyleable) grid item containing anonymous item 3.
  4. grid item containing three blocks in succession:
    • Anonymous block containing item 4.
    • <q> element block containing item 4.
    • Anonymous block containing item 4.

注意: 元素间的空白会消失:它不会成为自己独立的网格项目,即使元素间的文本确实会被包装在匿名网格项目中。

注意: 匿名项目的盒无法设置样式,因为没有元素可以为其分配样式规则。然而,其内容将从网格容器继承样式(例如字体设置)。

6.1. 网格项目显示

网格项目 为其内容 建立一个独立的格式化上下文。但是,网格项目是 网格级 (grid-level) 盒,而不是块级盒:它们参与其容器的 网格格式化上下文,而不是块格式化上下文。

如果元素最近的祖先元素(跳过 display:contents 祖先)的 计算后 display 值为 gridinline-grid,则元素自身的 display 值会被 块级化 (blockified)。(详见 CSS2.1§9.7 [CSS2]CSS Display 3 § 2.7 自动盒类型转换 获取有关此类 display 值转换的详细信息。)

注意: 即使 gridinline-grid 元素最终没有生成 网格容器 盒(例如,当它被 替换 (replaced) 或处于 display: none 子树中时),块级化仍然会发生。

注意: 某些 display 值通常会触发在原始盒周围创建匿名盒。如果此类盒是 网格项目,它会先被块级化,因此不会发生匿名盒创建。例如,两个具有 display: table-cell 的连续 网格项目 将变为两个独立的 display: block 网格项目,而不是被包装在一个单一的匿名表格中。

6.2. 网格项目尺寸

网格项目 在其 网格区域 定义的包含块内设置尺寸。

给定维度中 自动尺寸 (automatic sizes)网格项目 计算因其 自对齐值 (self-alignment values) 而异

normal

如果网格项目没有 首选宽高比 (preferred aspect ratio),且在相关轴上没有 自然尺寸 (natural size)(如果是 替换元素),则网格项目尺寸计算方式与 align-self: stretch 相同。

否则,网格项目根据相应轴的块级元素尺寸计算规则保持一致。(请参阅 CSS 2 § 10 视觉格式化模型细节。)

stretch

使用非替换盒的 内联尺寸 计算规则(定义在 CSS 2 § 10.3.3 正常流中的块级非替换元素),即 拉伸拟合尺寸 (stretch-fit size)

注意: 如果该项目的尺寸在另一个轴上也受到约束,这可能会扭曲具有 首选宽高比 的项目的宽高比。

所有其他值

将该项目尺寸调整为 fit-content

以下信息表总结了网格项目的自动尺寸调整:
网格项目自动尺寸行为摘要
对齐非替换元素尺寸替换元素尺寸
normal 填充网格区域使用 自然尺寸
stretch 填充网格区域填充网格区域
start/center/等fit-content 尺寸调整(像浮动一样)使用 自然尺寸

注意: min-widthmin-heightauto 值以类似于影响 弹性项目 主尺寸的方式影响相关轴上的轨道尺寸调整。请参阅 § 6.6 网格项目的自动最小尺寸

6.3. 重排网格项目:order 属性

order 属性也适用于 网格项目。它会影响它们的 自动放置绘制顺序

与重排弹性项目一样,order 属性仅应在视觉顺序需要与语音和导航顺序 不同步 时使用;否则应改为重新排列基础文档源码。请参阅 [CSS-FLEXBOX-1] 中的 CSS Flexbox 1 § 5.4.1 重排与无障碍访问

6.4. 网格项目的外边距与内边距

由于相邻的网格项目独立地包含在其 网格区域 形成的包含块内,因此相邻 网格项目 的外边距不会 重叠 (collapse)

网格项目 上的百分比外边距和内边距,像 块盒 上的百分比一样,是根据其 包含块内联尺寸 进行解析的,例如在水平 书写模式 (writing modes) 中,左/右/上/下百分比都根据其 包含块宽度 进行解析。

自动外边距会扩展以吸收相应维度的额外空间,因此可用于对齐。请参阅 § 10.2 使用 auto 外边距对齐

6.5. Z 轴排序:z-index 属性

网格项目 在定位到相交的 网格区域 时,甚至由于负外边距或定位而放置在不相交区域时,都可能会重叠。网格项目 的绘制顺序与内联块完全相同 [CSS2],只是使用 order 修改后的文档顺序 代替原始文档顺序,并且除 auto 之外的 z-index 值会创建堆叠上下文,即使 positionstatic(表现得完全像 positionrelative)。因此,z-index 属性可以很容易地用于控制网格项目的 Z 轴顺序。

注意:定位在网格项目之外的后代仍然参与由该网格项目建立的任何堆叠上下文。

下图展示了几个重叠的网格项目,结合使用隐式源码顺序和显式 z-index 来控制它们的堆叠顺序。
由 z-index 和源码顺序控制的绘制顺序。
<style type="text/css">
#grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: 1fr 1fr
}
#A { grid-column: 1 / span 2; grid-row: 2; align-self: end; }
#B { grid-column: 1; grid-row: 1; z-index: 10; }
#C { grid-column: 2; grid-row: 1; align-self: start; margin-left: -20px; }
#D { grid-column: 2; grid-row: 2; justify-self: end; align-self: start; }
#E { grid-column: 1 / span 2; grid-row: 1 / span 2;
     z-index: 5; justify-self: center; align-self: center; }
</style>

<div id="grid">
  <div id="A">A</div>
  <div id="B">B</div>
  <div id="C">C</div>
  <div id="D">D</div>
  <div id="E">E</div>
</div>

6.6. 网格项目的自动最小尺寸

注意: 本节(以及本规范其余部分)中使用的许多尺寸调整术语都在 CSS 固有与非固有尺寸调整 (CSS Intrinsic and Extrinsic Sizing) [CSS-SIZING-3] 中定义。

为了给 网格项目 提供更合理的默认 最小尺寸 (minimum size),其 自动最小尺寸 (automatic minimum size) 在给定轴上的使用值是 基于内容的最小尺寸 (content-based minimum size),如果满足以下所有条件:

否则,自动最小尺寸 照常为零。

注意: 基于内容的最小尺寸 是一种 固有尺寸贡献 (intrinsic size contribution),因此 CSS Sizing 3 § 5.2 固有贡献 中的规定适用。

网格项目 在给定维度上的 基于内容的最小尺寸 (content-based minimum size) 是其 指定尺寸建议 (specified size suggestion)(如果存在),否则是其 转换尺寸建议 (transferred size suggestion)(如果存在且元素是 替换元素),否则是其 内容尺寸建议 (content size suggestion)(见下文)。但是,如果 网格项目 在给定维度上仅跨越具有 固定 (fixed) 最大轨道尺寸函数 (max track sizing function)网格轨道,则其在该维度上的 指定尺寸建议内容尺寸建议(以及其从该维度输入到相反维度 转换尺寸建议 的输入)进一步被夹紧为小于或等于 拉伸拟合 (stretch fit)网格区域 在该维度上的最大尺寸,该最大尺寸由这些 网格轨道最大轨道尺寸函数 加上任何中间的 固定 排水沟(间隔) 之和表示。

在所有情况下,尺寸建议还会受到受影响轴上最大尺寸(如果该尺寸是确定的)的限制。如果项目是一个可压缩替换元素,并且在相关轴上具有确定的首选尺寸最大尺寸,则尺寸建议将由这些尺寸封顶;在此过程中,这些尺寸中任何不确定的百分比都将按零解析(并被视为确定的)。

注意:fit-content() 的参数不会固定最大轨道尺寸函数那样限制基于内容的最小尺寸

此计算中使用的内容尺寸建议指定尺寸建议转换尺寸建议考虑了相关的最小/最大/首选尺寸属性,以便基于内容的最小尺寸不会干扰作者提供的任何约束,具体定义如下。

指定尺寸建议
如果项目在相关轴上的首选尺寸确定的,则指定尺寸建议即为该尺寸。否则该建议未定义。
转换尺寸建议
如果项目具有首选纵横比,且其在相反轴上的首选尺寸确定的,则转换尺寸建议为该尺寸(如果相反轴的最小尺寸最大尺寸确定的,则受其限制),并通过纵横比转换。否则该建议未定义。

如果项目在相关轴上有确定的首选尺寸最大尺寸,则转换尺寸建议将由这些尺寸封顶;在此过程中,这些尺寸中任何不确定的百分比都将按零解析(并被视为确定的)。

内容尺寸建议
内容尺寸建议是在相关轴上的最小内容尺寸;如果项目具有首选纵横比,则受任何确定的相反轴的最小尺寸最大尺寸(通过纵横比转换)的限制。

为了计算盒子的固有尺寸(例如盒子的最小内容尺寸),基于内容的最小尺寸会导致盒子在该轴上的尺寸变为不确定(即使例如其 width 属性指定了确定的尺寸)。请注意,这意味着根据此尺寸计算出的百分比将表现为 auto

除了计算固有尺寸之外,基于内容的最小尺寸(不同于显式的 min-content最小尺寸)不会强制盒子的尺寸变为不确定。但是,如果百分比是在应用此最小尺寸之前根据盒子尺寸解析的,则必须在应用之后根据新尺寸重新解析。

请注意,虽然基于内容的最小尺寸通常是合适的,并且有助于防止内容重叠或溢出容器,但在某些情况下它并不合适。

特别地,如果网格布局被用于文档的主要内容区域,最好设置一个显式的字体相对最小宽度,例如 min-width: 12em。基于内容的最小宽度可能会导致大型表格或大图像撑开整个内容区域,甚至进入溢出区域,从而使文本行变得不必要地长且难以阅读。

另请注意,当在具有大量内容的项上使用基于内容的尺寸调整时,布局引擎必须在找到其最小尺寸之前遍历所有这些内容,而如果作者设置了显式最小值,则无需这样做。(对于内容较少的项,此遍历是微不足道的,因此不是性能问题。)

7. 定义网格

7.1. 显式网格

这三个属性 grid-template-rowsgrid-template-columnsgrid-template-areas 共同通过指定其显式网格轨道来定义网格容器显式网格。最终网格可能会因放置在显式网格之外的网格项而变大;在这种情况下,将创建隐式轨道,这些隐式轨道将由 grid-auto-rowsgrid-auto-columns 属性来调整大小。

显式网格的尺寸由 grid-template-areas 定义的行/列数与 grid-template-rows/grid-template-columns 定义的行/列数中的较大者决定。任何由 grid-template-areas 定义但未由 grid-template-rows/grid-template-columns 定义大小的行/列,其尺寸取自 grid-auto-rows/grid-auto-columns 属性。如果这些属性没有定义任何显式轨道,则显式网格在每个轴上仍包含一条网格线

网格定位属性中的数字索引是从显式网格的边缘开始计数的。正索引从起始 (start)侧计数(起始最靠前的显式线从 1 开始),而负索引从结束 (end)侧计数(结束最靠前的显式线从 -1 开始)。

gridgrid-template 属性是简写属性,可用于同时设置所有三个显式网格属性grid-template-rowsgrid-template-columnsgrid-template-areas)。grid 简写还会重置控制隐式网格的属性,而 grid-template 属性则保持它们不变。

7.2. 显式轨道尺寸:grid-template-rowsgrid-template-columns 属性

名称grid-template-columns, grid-template-rows
none | <track-list> | <auto-track-list>
初始值 none(无)
应用于 网格容器
可继承
百分比 参考内容区域的相应维度
计算值 关键字 none计算后的轨道列表
规范顺序 按语法
动画类型 如果列表长度匹配,则按计算后的轨道列表中每项的计算值类型进行插值(参见 § 7.2.5 轨道列表的计算值§ 7.2.3.3 repeat() 的插值/组合);否则进行离散插值

这些属性以空格分隔的轨道列表形式,指定网格线名称轨道尺寸函数grid-template-columns 属性指定网格列的轨道列表,而 grid-template-rows 指定网格行的轨道列表

值的含义如下:

none(无)
表明此属性不会创建任何显式网格轨道(尽管显式网格轨道仍可能由 grid-template-areas 创建)。

注意:在没有显式网格的情况下,任何行/列都将隐式生成,其大小将由 grid-auto-rowsgrid-auto-columns 属性确定。

<track-list> | <auto-track-list>
轨道列表指定为一系列轨道尺寸函数线名称。每个轨道尺寸函数都可以指定为长度、网格容器尺寸的百分比、占据列或行的内容的度量,或者是网格中可用空间的分数。它还可以使用 minmax() 符号指定为一个范围,该范围可以结合上述任何机制,分别为列或行指定最小最大轨道尺寸函数

轨道列表的语法如下

<track-list>          = [ <line-names>? [ <track-size> | <track-repeat> ] ]+ <line-names>?
<auto-track-list>     = [ <line-names>? [ <fixed-size> | <fixed-repeat> ] ]* <line-names>? <auto-repeat>
                        [ <line-names>? [ <fixed-size> | <fixed-repeat> ] ]* <line-names>?
<explicit-track-list> = [ <line-names>? <track-size> ]+ <line-names>?

<track-size>          = <track-breadth> | minmax( <inflexible-breadth> , <track-breadth> ) | fit-content( <length-percentage [0,∞]> )
<fixed-size>          = <fixed-breadth> | minmax( <fixed-breadth> , <track-breadth> ) | minmax( <inflexible-breadth> , <fixed-breadth> )
<track-breadth>       = <length-percentage [0,∞]> | <flex [0,∞]> | min-content | max-content | auto
<inflexible-breadth>  = <length-percentage [0,∞]> | min-content | max-content | auto
<fixed-breadth>       = <length-percentage [0,∞]>
<line-names>          = '[' <custom-ident>* ']'

其中组件值的定义如下...

7.2.1. 轨道尺寸

<length-percentage [0,∞]>
非负长度或百分比,由 CSS3 Values 定义。[CSS-VALUES-3]

<percentage> 值相对于网格容器在列网格轨道中的内联尺寸,以及网格容器在行网格轨道中的块尺寸。如果网格容器的大小取决于其轨道的大小,则为了计算网格容器的固有尺寸,<percentage> 必须被视为 auto,并在随后布局网格及其项目时,根据由此产生的网格容器尺寸进行解析。

<flex [0,∞]>
具有 fr 单位的非负维度,指定轨道的弹性系数 (flex factor)。每个 <flex> 大小的轨道根据其弹性系数占据剩余空间的一部分。例如,对于 1fr 2fr 的轨道列表,这些轨道将分别占据剩余空间的 ⅓ 和 ⅔。有关更多详细信息,请参阅 § 7.2.4 弹性长度:fr 单位

注意:如果弹性系数之和小于 1,它们将仅占据剩余空间的相应比例,而不是扩展以填满整个空间。

当出现在 minmax() 符号之外时,隐含一个自动最小值(即 minmax(auto, <flex>))。

minmax(min, max)
定义一个大于或等于 min 且小于或等于 max 的尺寸范围。如果 max 小于 min,则 max 将以 min 为底(实质上产生 minmax(min, min))。作为最大值,<flex> 值设置轨道的弹性系数;它作为最小值是无效的。

注意:本规范的未来级别可能会允许 <flex> 作为最小值,并将更新轨道尺寸算法以正确处理此问题。

auto
作为最大值:表示占据网格轨道网格项的最大最大内容贡献;然而,与 max-content 不同,它允许通过 align-contentjustify-content 属性扩展轨道。

作为最小值:表示占据网格轨道网格项的最大最小尺寸(由 min-width/min-height 指定)。(最初这通常但不总是等于 min-content 最小值—​参见 § 6.6 网格项的自动最小尺寸。)

当出现在 minmax() 符号之外时:等同于 minmax(auto, auto),表示上述最小值和最大值之间的范围。(在最简单的情况下,这类似于 minmax(min-content, max-content),但具有额外的能力。)

max-content
表示占据网格轨道网格项的最大最大内容贡献
min-content
表示占据网格轨道网格项的最大最小内容贡献
fit-content( <length-percentage> )
表示公式 max(minimum, min(limit, max-content)),其中 minimum 表示一个 auto 最小值(通常但不总是等于 min-content 最小值),limit 是作为参数传递给 fit-content()轨道尺寸函数。这本质上被计算为 minmax(auto, max-content)minmax(auto, limit) 中的较小者。
给定以下 grid-template-columns 声明
grid-template-columns: 100px 1fr max-content minmax(min-content, 1fr);

创建了五条网格线

  1. 网格容器的起始边缘。
  2. 距离网格容器起始边缘 100px 处。
  3. 距离前一条线一段距离,等于剩余空间的一半(网格容器的宽度减去非弹性网格轨道的宽度)。
  4. 距离前一条线一段距离,等于属于这两条线之间的列的任何网格项的最大尺寸。
  5. 距离前一条线一段距离,至少等于属于这两条线之间的列的任何网格项的最大最小尺寸,但不能大于剩余空间的另一半。

如果非弹性尺寸(100px, max-content, 和 min-content)之和大于网格容器的宽度,则最后一条网格线将距离网格容器的起始边缘一段等于其总和的距离(1fr 尺寸都解析为 0)。如果总和小于网格容器的宽度,则最后一条网格线将正好位于网格容器的结束边缘。只要网格轨道尺寸中存在至少一个 <flex> 值,通常就是这种情况。

有效网格轨道定义的其他示例
/* examples of valid track definitions */
grid-template-rows: 1fr minmax(min-content, 1fr);
grid-template-rows: 10px repeat(2, 1fr auto minmax(30%, 1fr));
grid-template-rows: calc(4em - 5px);

注意:网格的尺寸并不纯粹是轨道尺寸的总和,因为 row-gap, column-gapjustify-content, align-content 可以在轨道之间增加额外的空间。

7.2.2. 命名网格线:[<custom-ident>*] 语法

虽然网格线总是可以通过其数字索引来引用,但线名称可以使网格定位属性更易于理解和维护。线名称可以通过 grid-template-rowsgrid-template-columns 属性显式分配,或者通过 grid-template-areas 属性通过命名网格区域隐式分配

例如,以下代码为网格中的所有线提供了有意义的名称。请注意,有些线有多个名称。
#grid {
  display: grid;
  grid-template-columns: [first nav-start] 150px [main-start] 1fr [last];
  grid-template-rows: [first header-start] 50px [main-start] 1fr [footer-start] 50px [last];
}
Image: Named Grid Lines.
命名网格线。

线名称不能是 spanauto,即 <line-names> 产生式中的 <custom-ident> 排除关键字 spanauto

7.2.3. 重复行和列:repeat() 符号

repeat() 符号表示轨道列表的重复片段,允许以更紧凑的形式书写大量呈现重复模式的列或行。

此示例展示了编写相同网格定义的两种等效方式。这两个声明都产生了四个 250px 宽的“主”列,由 10px 的“间距”列包围。
grid-template-columns: 10px [col-start] 250px [col-end]
                       10px [col-start] 250px [col-end]
                       10px [col-start] 250px [col-end]
                       10px [col-start] 250px [col-end] 10px;
/* same as above, except easier to write */
grid-template-columns: repeat(4, 10px [col-start] 250px [col-end]) 10px;
7.2.3.1. repeat() 的语法

repeat() 语法的通用形式大致如下

repeat( [ <integer [1,∞]> | auto-fill | auto-fit ] , <track-list> )

第一个参数指定重复次数。第二个参数是轨道列表,重复该次数。但是,存在一些限制

因此 repeat() 符号的精确语法有几种形式

<track-repeat> = repeat( [ <integer [1,∞]> ] , [ <line-names>? <track-size> ]+ <line-names>? )
<auto-repeat>  = repeat( [ auto-fill | auto-fit ] , [ <line-names>? <fixed-size> ]+ <line-names>? )
<fixed-repeat> = repeat( [ <integer [1,∞]> ] , [ <line-names>? <fixed-size> ]+ <line-names>? )

如果 repeat() 函数最终将两个 <line-names> 放置在一起,名称列表将被合并。例如,repeat(2, [a] 1fr [b]) 等同于 [a] 1fr [b a] 1fr [b]

7.2.3.2. 重复填充:auto-fillauto-fit 重复

当给出 auto-fill 作为重复次数时,如果网格容器在相关轴上有确定的首选尺寸最大尺寸,则重复次数是不会导致网格溢出其网格容器内容框(考虑 gap)的最大可能正整数;如果任何次数的重复都会导致溢出,则为 1 次重复。否则,如果网格容器在相关轴上有确定的最小尺寸,则重复次数是满足该最小要求的最小可能正整数。否则,指定的轨道列表仅重复一次。

出于此目的,每个轨道被视为其最大轨道尺寸函数(如果该函数是确定的),否则视为其最小轨道尺寸函数(如果该函数是确定的)。如果两者都是确定的,则以最小轨道尺寸函数为底,对最大轨道尺寸函数进行限制。如果两者都不确定,则重复次数为 1。

例如,以下代码将创建尽可能多的 25 字符列以适应窗口宽度。如果有任何剩余空间,它将被分配给 25 字符列。
body {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(25ch, 1fr));
}

auto-fit 关键字的行为与 auto-fill 相同,不同之处在于,在网格项定位之后,任何空的重复轨道都会折叠。空轨道是指没有流内网格项被放置在其中或跨越其中的轨道。(如果所有轨道都为空,这可能导致所有轨道都被折叠。)

折叠的网格轨道被视为具有 0px 的固定轨道尺寸函数,并且其两侧的间距—​包括通过分布对齐分配的任何空间—​都会折叠

为了找到自动重复轨道的数量,UA 必须将轨道尺寸下限设为 UA 指定的值,以避免除以零。建议此下限为 1px

7.2.3.3. repeat() 的插值/组合

如果两个 repeat() 符号具有相同的第一个参数(重复次数)和第二个参数(轨道列表)中相同数量的轨道,则它们通过按计算值组合其计算后的轨道列表中的每个组件(就像组合顶级轨道列表一样)来组合。否则,它们离散地组合。

7.2.4. 弹性长度:fr 单位

弹性长度<flex> 是一个具有 fr 单位的维度,它表示网格容器剩余空间的一部分。以 fr 单位调整大小的轨道被称为弹性轨道,因为它们响应剩余空间的方式类似于具有零基础尺寸的弹性项目填充弹性容器中的空间。

剩余空间的分配发生在所有非弹性轨道尺寸函数达到其最大值之后。此类行或列的总大小从可用空间中减去,从而得出剩余空间,然后根据其弹性系数分配给以弹性大小调整的行和列。

每列或每行占剩余空间的份额可以计算为:<flex> * <剩余空间> / <所有弹性系数之和>

0fr 和 1fr 之间的 <flex> 值具有一种较为特殊的行为:当弹性系数之和小于 1 时,它们将占据剩余空间不足 100% 的部分。

轨道的 <flex> 值实际上是对剩余空间某种比例的请求,1fr 意味着“100% 的剩余空间”;如果该轴上的轨道总共请求超过 100%,请求将被重新平衡以保持相同的比例,但完全用掉 100% 的空间。然而,如果轨道请求少于全部数量(例如三个轨道各为 .25fr),那么它们每个都将得到它们请求的确切数量(每个获得 25% 的剩余空间,最后 25% 保持未填充)。有关剩余空间如何分配的精确细节,请参阅 § 11.7 展开弹性轨道

这种模式对于 fr 值趋近于零(意味着轨道不想要任何剩余空间)时的连续行为是必需的。如果没有这个,一个 1fr 的轨道将占据所有剩余空间;但 0.1fr 的轨道,0.01fr 的轨道等等也会如此,直到该值小到下溢为零,轨道突然不占据任何剩余空间。有了这种行为,轨道反而随着其弹性系数缩小到 1fr 以下而逐渐占用较少的剩余空间,平滑过渡到在零时占用零剩余空间。

除非“部分填充”行为是明确想要的,否则作者应该坚持使用 ≥ 1 的值;例如,使用 1fr2fr 通常比使用 .33fr.67fr 更好,因为如果添加或移除轨道,前者更有可能按预期表现。

当可用空间无限时(当网格容器的宽度或高度是不确定的时会发生),以弹性大小调整的网格轨道将根据其内容进行调整大小,同时保持其各自的比例。每个弹性大小轨道的使用尺寸是通过确定每个弹性轨道的大小 max-content 并将该大小除以各自的弹性系数来确定“假设的 1fr 尺寸”计算得出的。其中的最大值被用作解析的 1fr 长度(弹性分数),然后将其乘以每个网格轨道弹性系数以确定其最终尺寸。

注意:<flex> 值不是 <length>(它们也不与 <length> 兼容,就像某些 <percentage> 值一样),因此它们不能在 calc() 表达式中表示或与其他单位类型组合。

7.2.5. 轨道列表的计算值

计算后的轨道列表是一个在线名称集轨道区段之间交替的列表,第一项和最后一项均为线名称集

线名称集是一个(可能为空的)代表线名称的标识符集合

轨道区段要么是

7.2.6. 轨道列表的解析值

grid-template-rowsgrid-template-columns 属性是解析值特殊情况属性[CSSOM]

当元素生成网格容器盒子时,其 grid-template-rowsgrid-template-columns 属性的解析值使用值,序列化方式如下

上述列表的第一点意味着隐式轨道被序列化为 grid-template-rows 等的一部分,尽管作者不能在这些属性中实际指定隐式轨道尺寸!因此,grid-template-rowsgrid-template-columns 的值可能无法正确往返。
const s = getComputedStyle(gridEl);
gridEl.style.gridTemplateRows = s.gridTemplateRows;
// Code like this should be a no-op,
// but if there are any implicit rows,
// this will convert them into explicit rows,
// possibly changing how grid items are positioned
// and altering the overall size of the grid!

这是早期实现的一个偶然属性,在没有过多考虑的情况下泄露到了后续的实现中。我们打算将其从规范中删除,但要在我们定义好用于获取有关隐式轨道信息的 CSSOM API 之后,因为目前这是获取该信息的唯一方式,且许多页面都依赖于此。

否则(例如当元素具有 display: none 或者不是网格容器时),解析值仅为计算值

<style>
#grid {
  width: 500px;
  grid-template-columns:
    [a]     auto
    [b]     minmax(min-content, 1fr)
    [b c d] repeat(2, [e] 40px)
            repeat(5, auto);
}
</style>
<div id="grid">
  <div style="grid-column-start: 1; width: 50px"></div>
  <div style="grid-column-start: 9; width: 50px"></div>
</div>
<script>
  var gridElement = document.getElementById("grid");
  getComputedStyle(gridElement).gridTemplateColumns;
  // [a] 50px [b] 320px [b c d e] 40px [e] 40px 0px 0px 0px 0px 50px
</script>

注意:通常情况下,解析值就是计算值,除了少数遗留的 2.1 属性外。然而,为了与本模块的早期实现兼容,我们需要将 grid-template-rowsgrid-template-columns 定义为返回使用值。

CSS 工作组正在考虑是否也对网格定位属性返回使用值,并正在寻求反馈,特别是来自实现者的反馈。参见讨论

7.3. 命名区域:grid-template-areas 属性

名称grid-template-areas
none | <string>+
初始值 none(无)
应用于 网格容器
可继承
百分比 不可用
计算值 关键字 none 或字符串值列表
规范顺序 按语法
动画类型 离散 (discrete)

此属性指定命名网格区域,它们不与任何特定的网格项相关联,但可以从网格定位属性中引用。grid-template-areas 属性的语法还提供了网格结构的可视化,使网格容器的整体布局更易于理解。

值的含义如下:

none(无)
表明此属性不会定义任何命名网格区域,同样也不会定义任何显式网格轨道(尽管显式网格轨道仍可能由 grid-template-columnsgrid-template-rows 创建)。

注意:在没有显式网格的情况下,任何行/列都将隐式生成,其大小将由 grid-auto-rowsgrid-auto-columns 属性确定。

<string>+
grid-template-areas 属性列出的每个单独字符串创建一个行,并且在按如下方式解析时,为字符串中的每个单元格创建一个列

使用最长匹配语义,将字符串标记化为以下标记列表

  • 一系列标识符代码点,代表一个名称由其代码点组成的命名单元格标记
  • 一个或多个 "." (U+002E FULL STOP) 的序列,代表一个空单元格标记
  • 一系列空白符,不代表任何内容(不产生标记)。
  • 任何其他字符的序列,代表一个垃圾标记

注意:这些规则可以产生与 <ident> 语法不匹配的单元格名称,例如 "1st 2nd 3rd",这在其他属性中按名称引用这些区域时需要转义,例如 grid-row: \31st; 以引用名为 1st 的区域。

所有字符串必须定义相同数量的单元格标记(命名单元格标记和/或空单元格标记),并且至少有一个单元格标记,否则声明无效。如果一个命名网格区域跨越多个网格单元格,但这些单元格没有形成一个单一的填充矩形,则声明无效。

注意:非矩形或不连续的区域可能会在本模块的未来版本中被允许。

在此示例中,grid-template-areas 属性用于创建一个页面布局,其中为标题内容(head)、导航内容(nav)、页脚内容(foot)和主要内容(main)定义了区域。因此,该模板创建了三行两列,并带有四个命名网格区域head 区域跨越两列和网格的第一行。
#grid {
  display: grid;
  grid-template-areas: "head head"
                       "nav  main"
                       "foot ...."
}
#grid > header { grid-area: head; }
#grid > nav    { grid-area: nav; }
#grid > main   { grid-area: main; }
#grid > footer { grid-area: foot; }

7.3.1. 模板字符串的序列化

当序列化 grid-template-areas<string> 值的指定值计算值时,每个空单元格标记被序列化为单个 "." (U+002E FULL STOP),连续的单元格标记由单个空格 (U+0020 SPACE) 分隔,所有其他空白符均被省略。

7.3.2. 隐式分配的线名称

grid-template-areas 属性从模板中的命名网格区域生成隐式分配的线名称。对于每个命名网格区域 foo,会创建四个隐式分配的线名称:两个名为 foo-start,命名为该命名网格区域的行起始和列起始线;两个名为 foo-end,命名为该命名网格区域的行结束和列结束线。

这些隐式分配的线名称的行为与其他任何线名称一样,只是它们不会出现在 grid-template-rows/grid-template-columns 的值中。即使定义了具有相同名称的显式分配的线名称隐式分配的线名称也只是更多同名的线而已。

7.3.3. 隐式命名的区域

由于命名网格区域是由它产生的隐式分配的线名称所引用的,因此显式添加相同形式(foo-start/foo-end)的命名线有效地创建了一个命名网格区域。此类隐式命名的区域不会出现在 grid-template-areas 的值中,但仍然可以被网格定位属性所引用。

7.4. 显式网格简写:grid-template 属性

名称grid-template
none | [ <'grid-template-rows'> / <'grid-template-columns'> ] | [ <line-names>? <string> <track-size>? <line-names>? ]+ [ / <explicit-track-list> ]?
初始值 none(无)
应用于 网格容器
可继承 见各个属性
百分比 见各个属性
计算值 见各个属性
动画类型 见各个属性
规范顺序 按语法

grid-template 属性是用于在单个声明中设置 grid-template-columns, grid-template-rowsgrid-template-areas简写属性。它有几种不同的语法形式

none(无)
将所有三个属性设置为其初始值 (none)。
<'grid-template-rows'> / <'grid-template-columns'>
分别将 grid-template-rowsgrid-template-columns 设置为指定值,并将 grid-template-areas 设置为 none
grid-template: auto 1fr / auto 1fr auto;

等同于

grid-template-rows: auto 1fr;
grid-template-columns: auto 1fr auto;
grid-template-areas: none;
[ <line-names>? <string> <track-size>? <line-names>? ]+ [ / <explicit-track-list> ]?

此语法允许作者将轨道名称和尺寸与其各自的网格区域内联对齐。

grid-template: [header-top] "a   a   a"     [header-bottom]
                 [main-top] "b   b   b" 1fr [main-bottom]
                          / auto 1fr auto;

等同于

grid-template-areas: "a a a"
                     "b b b";
grid-template-rows: [header-top] auto [header-bottom main-top] 1fr [main-bottom];
grid-template-columns: auto 1fr auto;

并创建以下网格

  • Three columns, sized auto, 1fr, and auto, respectively
  • Two rows sized as auto and 1fr, respectively.
  • A line named both “header-top” and “a-start” at the top, a line with four names—​“header-bottom”, “main-top”, “a-end”, and “b-start”—​in the middle, a line named “main-bottom” and “b-end” at the bottom.
  • A line named “a-start” and “b-start” on the left edge, and a line named “a-end” and “b-end” on the right edge.
上述声明创建的网格。(“a/b-start/end”名称由命名网格区域隐式分配。)

注意:请注意,repeat() 函数在这些轨道列表中是不允许的,因为轨道旨在在视觉上与“ASCII 艺术”中的行/列一一对应。

注意:grid 简写接受相同的语法,但也会将隐式网格属性重置为初始值。除非作者希望它们单独层叠,否则建议使用 grid 而不是 grid-template

7.5. 隐式网格

grid-template-rows, grid-template-columnsgrid-template-areas 属性定义了构成显式网格的固定数量的轨道。当网格项被定位在这些边界之外时,网格容器通过向网格添加隐式网格线来生成隐式网格轨道。这些线与显式网格一起构成隐式网格grid-auto-rowsgrid-auto-columns 属性调整这些隐式网格轨道的大小,以及任何由 grid-template-areas 创建但未被 grid-template-rowsgrid-template-columns 显式调整大小的显式网格轨道的大小。

grid-auto-flow 属性控制没有显式位置的网格项的自动放置。一旦显式网格被填满(或者如果没有显式网格),自动放置也将导致隐式网格轨道的生成。

grid 简写属性可以在单个声明中设置隐式网格属性grid-auto-flow, grid-auto-rowsgrid-auto-columns)以及显式网格属性

7.6. 隐式轨道尺寸:grid-auto-rowsgrid-auto-columns 属性

名称grid-auto-columns, grid-auto-rows
<track-size>+
初始值 auto
应用于 网格容器
可继承
百分比 参见 轨道尺寸
计算值 参见 轨道尺寸
规范顺序 按语法
动画类型 如果列表长度匹配,则按计算值类型进行插值;否则进行离散插值

grid-auto-columnsgrid-auto-rows 属性指定未由 grid-template-rowsgrid-template-columns 分配尺寸的轨道的尺寸。如果给出了多个轨道尺寸,则根据需要重复该模式以查找受影响轨道的尺寸。最后一个显式调整大小的轨道之后的第一条轨道接收第一个指定尺寸,以此类推;而显式网格之前的最后一个隐式网格轨道接收最后一个指定尺寸,以此类推。

注意:如果一个网格项被定位到一个未由 grid-template-rows/grid-template-columns 和/或 grid-template-areas 显式声明的行或列中,则会创建隐式网格轨道来容纳它。这可以通过显式定位到超出范围的行或列,或者通过创建额外行或列的自动放置算法发生。

<style>
  #grid {
    display: grid;
    grid-template-columns: 20px;
    grid-auto-columns: 40px;
    grid-template-rows: 20px;
    grid-auto-rows: 40px;
  }
  #A { grid-column: 1; grid-row: 1; }
  #B { grid-column: 2; grid-row: 1; }
  #C { grid-column: 1; grid-row: 2; }
  #D { grid-column: 2; grid-row: 2; }
</style>

<div id="grid">
  <div id="A">A</div>
  <div id="B">B</div>
  <div id="C">C</div>
  <div id="D">D</div>
</div>
一个 2×2 网格,在第一行+第一列中有一个显式的 20px×20px 网格单元,以及由于为容纳额外网格项而生成的隐式 40px 列和行而产生的三个额外单元格。

7.7. 自动放置grid-auto-flow 属性

名称grid-auto-flow
[ row | column ] || dense
初始值 row
应用于 网格容器
可继承
百分比 不可用
计算值 指定的关键字
规范顺序 按语法
动画类型 离散 (discrete)

未显式放置的网格项自动放置算法自动放置到网格容器的未占用空间中。grid-auto-flow 控制自动放置算法的工作方式,具体指定自动放置的项目如何流入网格。有关自动放置算法精确工作方式的详细信息,请参阅 § 8.5 网格项定位算法

row
自动放置算法通过依次填充每一行来放置项目,并在必要时添加新行。如果未提供 rowcolumn,则假定为 row
column (列)
自动放置算法通过依次填充每一列来放置项目,并在必要时添加新列。
dense
如果指定,自动放置算法将使用“密集”打包算法,该算法尝试填充网格中较早的孔隙,如果较小的项目在后面出现。这样做可能会导致项目出现顺序混乱,以填补较大项目留下的空隙。

如果省略,则使用“稀疏”算法,其中放置算法在放置项目时只会向网格中“向前”移动,绝不会回溯以填补空隙。这确保了所有自动放置的项目都按“顺序”出现,即使这留下了本可以由后面项目填补的空隙。

注意:本模块的未来级别预计将增加一个值,将自动定位的项目合并流入单个“默认”单元格中。

自动放置(Auto-placement)按 网格项修正后的文档顺序 进行处理。

在下面的示例中,有三列,每一列都根据其内容自动调整大小。未显式定义任何行。grid-auto-flow 属性为 row,这指示网格从第一行开始,横跨其三列进行搜索,然后是下一行,并在需要时增加行,直到找到足够的空间来容纳任何自动放置的 网格项
Image: A form arranged using automatic placement.

一个使用自动放置排列的表单。

<style type="text/css">
form {
  display: grid;
  /* Define three columns, all content-sized,
     and name the corresponding lines. */
  grid-template-columns: [labels] auto [controls] auto [oversized] auto;
  grid-auto-flow: row dense;
}
form > label {
  /* Place all labels in the "labels" column and
     automatically find the next available row. */
  grid-column: labels;
  grid-row: auto;
}
form > input, form > select {
  /* Place all controls in the "controls" column and
     automatically find the next available row. */
  grid-column: controls;
  grid-row: auto;
}

#department-block {
  /* Auto place this item in the "oversized" column
     in the first row where an area that spans three rows
     won’t overlap other explicitly placed items or areas
     or any items automatically placed prior to this area. */
  grid-column: oversized;
  grid-row: span 3;
}

/* Place all the buttons of the form
   in the explicitly defined grid area. */
#buttons {
  grid-row: auto;

  /* Ensure the button area spans the entire grid element
     in the inline axis. */
  grid-column: 1 / -1;
  text-align: end;
}
</style>
<form>
  <label for="firstname">First name:</label>
  <input type="text" id="firstname" name="firstname">
  <label for="lastname">Last name:</label>
  <input type="text" id="lastname" name="lastname">
  <label for="address">Address:</label>
  <input type="text" id="address" name="address">
  <label for="address2">Address 2:</label>
  <input type="text" id="address2" name="address2">
  <label for="city">City:</label>
  <input type="text" id="city" name="city">
  <label for="state">State:</label>
  <select type="text" id="state" name="state">
    <option value="WA">Washington</option>
  </select>
  <label for="zip">Zip:</label>
  <input type="text" id="zip" name="zip">

  <div id="department-block">
    <label for="department">Department:</label>
    <select id="department" name="department" multiple>
      <option value="finance">Finance</option>
      <option value="humanresources">Human Resources</option>
      <option value="marketing">Marketing</option>
    </select>
  </div>

  <div id="buttons">
    <button id="cancel">Cancel</button>
    <button id="back">Back</button>
    <button id="next">Next</button>
  </div>
</form>

7.8. 网格定义简写:grid 属性

名称grid
<'grid-template'> | <'grid-template-rows'> / [ auto-flow && dense? ] <'grid-auto-columns'>? | [ auto-flow && dense? ] <'grid-auto-rows'>? / <'grid-template-columns'>
初始值 none(无)
应用于 网格容器
可继承 见各个属性
百分比 见各个属性
计算值 见各个属性
动画类型 见各个属性
规范顺序 按语法

grid 属性是一个 简写属性,它在单个声明中设置所有的 显式网格属性grid-template-rowsgrid-template-columnsgrid-template-areas)以及所有的 隐式网格属性grid-auto-rowsgrid-auto-columnsgrid-auto-flow)。(它不会重置 间距 (gutter) 属性。)

其语法与 grid-template 匹配,并额外增加了一种用于定义自动流 (auto-flow) 网格的语法形式。

<'grid-template'>
grid-template 的长属性设置为与 grid-template 相同,并将 grid-auto-* 的长属性设置为它们的初始值。
<'grid-template-rows'> / [ auto-flow && dense? ] <'grid-auto-columns'>?
[ auto-flow && dense? ] <'grid-auto-rows'>? / <'grid-template-columns'>
通过在一个轴上显式设置轨道(将 grid-template-rowsgrid-template-columns 设置为指定值,并将另一个设置为 none),并指定如何在另一个轴上自动重复轨道(将 grid-auto-rowsgrid-auto-columns 设置为指定值,并将另一个设置为 auto)来设置自动流。同时,grid-auto-flow 也会相应地设置为 rowcolumn,如果指定了 dense,则会包含该关键字。

所有其他的 grid 子属性都会重置为它们的初始值。

注意: 请注意,在单个 grid 声明中,只能指定显式属性 隐式网格属性。未指定的子属性将设置为它们的初始值,这符合 简写属性 的通用规则。

除了接受用于设置 显式网格grid-template 简写语法外,grid 简写还可以轻松设置自动格式化网格的参数。例如,grid: auto-flow 1fr / 100px; 等同于
grid-template: none / 100px;
grid-auto-flow: row;
grid-auto-rows: 1fr;
grid-auto-columns: auto;

同样,grid: none / auto-flow 1fr 等同于

grid-template: none;
grid-auto-flow: column;
grid-auto-rows: auto;
grid-auto-columns: 1fr;

在序列化时,如果所有 grid-auto-* 长属性都处于其初始值,则使用 grid-template 语法。

8. 放置网格项

每一个 网格项 都关联到一个 网格区域,这是由该 网格项 所占据的一组相邻的 网格单元 构成的矩形区域。这个 网格区域 定义了该 网格项包含块,在其中,自我对齐属性(justify-selfalign-self)决定了它们的实际位置。一个 网格项 所占据的单元格也会影响网格行和列的大小,这在 § 11 网格布局算法 中有定义。

一个 网格项网格区域网格 中的位置由其 放置 (placement) 定义,该放置由一个 网格位置 和一个 网格跨度 组成。

网格位置
网格项网格 中每个轴上的位置。网格位置 可以是 确定性的 (definite)(显式指定)或 自动的 (automatic)(由 自动放置 决定)。
网格跨度
网格项 在每个轴上占据多少个 网格轨道。在 Level 1 中,网格项网格跨度 总是 确定性的,如果在该轴上无法以其他方式确定,则默认在该轴上跨度为 1。

网格放置属性——即长属性 grid-row-startgrid-row-endgrid-column-startgrid-column-end,以及它们的简写属性 grid-rowgrid-columngrid-area——允许作者通过提供以下六个信息片段中的任何(或不提供)来指定 网格项放置位置

开始 起始行线 (row-start line)起始列线 (column-start line)
结束 (End) 结束行线 (row-end line)结束列线 (column-end line)
跨度 (Span) 行跨度 (row span)列跨度 (column span)

在给定维度中,对于 Start(起始)、End(结束)和 Span(跨度)中的任意两个指定确定值,即隐含了第三个值的确定性。

下表总结了网格位置或跨度为 确定性 (definite)自动 (automatic) 的条件。

立场跨度 (Span)
确定性 (Definite)至少指定了一条线显式、隐式或默认的跨度。
自动未显式指定任何线不适用

8.1. 网格放置的常见模式

本节是资料性的。

网格放置属性的长属性被组织为三个简写属性。

grid-area
grid-column grid-row
grid-column-start grid-column-end grid-row-start grid-row-end

8.1.1. 命名区域 (Named Areas)

可以通过在 grid-area 中指定区域名称,将项放置到 命名网格区域 中(例如 grid-template-areas 中模板生成的区域)。

article {
  grid-area: main;
  /* Places item into the named area "main". */
}

项也可以 部分地命名网格区域 对齐,而其他边缘则与其他线条对齐。

.one {
  grid-row-start: main;
  /* Align the row-start edge to the start edge of the "main" named area. */
}

8.1.2. 数字索引和跨度 (Numeric Indexes and Spans)

网格项可以通过数字进行定位和设置大小,这对于脚本驱动的布局特别有帮助。

.two {
  grid-row: 2;    /* Place item in the second row. */
  grid-column: 3; /* Place item in the third column. */
  /* Equivalent to grid-area: 2 / 3; */
}

默认情况下,网格项的跨度为 1。可以显式指定不同的跨度。

.three {
  grid-row: 2 / span 5;
  /* Starts in the 2nd row,
     spans 5 rows down (ending in the 7th row). */
}

.four {
  grid-row: span 5 / 7;
  /* Ends in the 7th row,
     spans 5 rows up (starting in the 2nd row). */
}

注意: 请注意,网格索引与 书写模式 (writing mode) 相关。例如,在像阿拉伯语这样从右向左的语言中,第一列是最右侧的列。

8.1.3. 命名线和跨度 (Named Lines and Spans)

线条无需通过数字计数,可以按其 线条名称 进行引用。

.five {
  grid-column: first / middle;
  /* Span from line "first" to line "middle". */
}

注意: 请注意,如果 命名网格区域 的名称与 线条名称 相同,放置算法将优先使用 命名网格区域 的线条。

如果存在多条同名的线条,它们实际上建立了一个命名的网格线集合,可以通过按名称过滤放置来专门索引这些线条。

.six {
  grid-row: text 5 / text 7;
  /* Span between the 5th and 7th lines named "text". */
  grid-row: text 5 / span text 2;
  /* Same as above - start at the 5th line named "text",
     then span across two more "text" lines, to the 7th. */
}

8.1.4. 自动放置 (Auto Placement)

一个 网格项 可以自动放置到下一个可用的空 网格单元 中,如果空间不足,则会扩展 网格

.eight {
  grid-area: auto; /* Initial value */
}

这可以用于,例如,在目录网站上以网格模式列出多个销售商品。

如果项需要占用多个单元格,自动放置可以与显式跨度结合使用。

.nine {
  grid-area: span 2 / span 3;
  /* Auto-placed item, covering two rows and three columns. */
}

自动放置算法 是横向搜索并增加行,还是纵向搜索并增加列,由 grid-auto-flow 属性控制。

注意: 默认情况下,自动放置算法 会在网格中线性搜索,不会回溯;如果为了放置更大的项而不得不跳过一些空位,它将不会返回去填充这些空位。若要更改此行为,请在 grid-auto-flow 中指定 dense 关键字。

8.2. 网格项放置与源码顺序

“能力越大,责任越大。”

网格放置属性 的能力允许内容在 网格 内自由排列和重新排序,使得视觉呈现可能与底层的文档源码顺序大相径庭。这些能力赋予作者极大的自由度来根据不同的设备和呈现模式调整渲染,例如使用 媒体查询。然而,它们不能替代正确的源码顺序

正确的源码顺序对于语音阅读、顺序导航(例如键盘导航)以及诸如搜索引擎、触觉浏览器等非 CSS 用户代理非常重要。网格放置 影响视觉呈现!这允许作者针对非 CSS/非视觉交互模式优化文档源码,并利用网格放置技术进一步操作视觉呈现,从而保持源码顺序的完整性。

8.3. 基于线的放置:grid-row-startgrid-column-startgrid-row-endgrid-column-end 属性

名称grid-row-startgrid-column-startgrid-row-endgrid-column-end
<grid-line>
初始值 auto
应用于 网格项 和以 网格容器 为包含块的绝对定位框。
可继承
百分比 不可用
计算值 指定的关键字、标识符和/或整数
规范顺序 按语法
动画类型 离散 (discrete)
<grid-line> =
  auto |
  <custom-ident> |
  [ [ <integer [-∞,-1]> | <integer [1,∞]> ] && <custom-ident>? ] |
  [ span && [ <integer [1,∞]> || <custom-ident> ] ]

grid-row-startgrid-column-startgrid-row-endgrid-column-end 属性通过为 网格项网格放置 提供一条线、一个跨度或什么都不提供(自动),从而确定 网格 中网格项的大小和位置,进而指定其 网格区域内联起始 (inline-start)块起始 (block-start)内联结束 (inline-end)块结束 (block-end) 边缘。

值的含义如下:

<custom-ident>
首先尝试将 网格区域 的边缘与 命名网格区域 匹配:如果存在一条 网格线,其 线条名称<custom-ident>-start (对于 grid-*-start) 或 <custom-ident>-end (对于 grid-*-end),则将第一条此类线条贡献给 网格项放置位置

注意: 命名网格区域 会自动生成此形式的 隐式分配的线条名称,因此指定 grid-row-start: foo 将选择该 命名网格区域 的起始边缘(除非在此之前已明确指定了另一条名为 foo-start 的线条)。

否则,将其视为好像指定了整数 1 以及 <custom-ident> 一样处理。

[ <integer [-∞,-1]> | <integer [1,∞]> ] && <custom-ident>?
将第 N网格线 贡献给 网格项放置位置。如果给出了负整数,则它将从 显式网格 的结束边缘开始反向计数。

如果名称以 <custom-ident> 的形式给出,则仅对具有该名称的线条进行计数。如果具有该名称的线条不足,则假设所有 隐式网格线 为了找到此位置的目的都具有该名称。

值为 0<integer> 会使声明无效。

span && [ <integer [1,∞]> || <custom-ident> ]
网格项放置位置 贡献一个 网格跨度,使得该 网格项网格区域 的相应边缘距离其在相应方向的对立边缘有 N 条线。例如,grid-column-end: span 2 表示从 grid-column-start 线开始向结束方向的第二条网格线。

如果名称以 <custom-ident> 的形式给出,则仅对具有该名称的线条进行计数。如果具有该名称的线条不足,则为了计算此跨度,假设 显式网格 侧面的所有 隐式网格线(对应于搜索方向)都具有该名称。

例如,给出以下声明
.grid { grid-template-columns: 100px; }
.griditem { grid-column: span foo / 4; }

网格容器 拥有一个具有两条网格线(编号为 1 和 2)的 显式网格网格项 的列结束边缘被指定在第 4 线,因此在 隐式网格 的结束侧生成了两条线。

其列起始边缘必须是它能在起始方向上找到的第一条“foo”线。然而,网格中没有“foo”线,所以唯一的可能性是 隐式网格 中的线。第 3 线不是候选者,因为它处于 显式网格 的结束侧,而 grid-column-start 跨度迫使它向起始方向搜索。因此,唯一的选择是让 隐式网格显式网格 的起始侧生成一条线。

结果的示意图。

如果省略了 <integer>,则默认为 1。负整数或零是无效的。

auto
该属性对 网格项放置位置 没有贡献,表示 自动放置 或默认跨度为 1。(见上文 § 8 放置网格项。)

在以上所有产生式中,<custom-ident> 额外排除了关键字 spanauto

给定一个单行、8 列的网格和以下 9 个命名线
1  2  3  4  5  6  7  8  9
+--+--+--+--+--+--+--+--+
|  |  |  |  |  |  |  |  |
A  B  C  A  B  C  A  B  C
|  |  |  |  |  |  |  |  |
+--+--+--+--+--+--+--+--+

以下声明将网格项放置在由索引指示的线条之间

grid-column-start: 4; grid-column-end: auto;
/* Line 4 to line 5 */

grid-column-start: auto; grid-column-end: 6;
/* Line 5 to line 6 */

grid-column-start: C; grid-column-end: C -1;
/* Line 3 to line 9 */

grid-column-start: C; grid-column-end: span C;
/* Line 3 to line 6 */

grid-column-start: span C; grid-column-end: C -1;
/* Line 6 to line 9 */

grid-column-start: span C; grid-column-end: span C;
/* Error: The end span is ignored, and an auto-placed
   item can’t span to a named line.
   Equivalent to ''grid-column: span 1;''. */

grid-column-start: 5; grid-column-end: C -1;
/* Line 5 to line 9 */

grid-column-start: 5; grid-column-end: span C;
/* Line 5 to line 6 */

grid-column-start: 8; grid-column-end: 8;
/* Error: line 8 to line 9 */

grid-column-start: B 2; grid-column-end: span 1;
/* Line 5 to line 6 */

8.3.1. 网格放置冲突处理

如果 网格项放置位置 包含两条线,且 起始 (start) 线比 结束 (end) 线更靠近结束方向,则交换这两条线。如果 起始 线 等于 结束 线,则移除 结束 线。

如果 放置位置 包含两个跨度,则移除由 结束 (end) 网格放置属性 所贡献的那一个。

如果 放置位置 仅包含一个命名线的跨度,则将其替换为跨度 1。

8.4. 放置简写属性:grid-columngrid-rowgrid-area 属性

名称grid-rowgrid-column
<grid-line> [ / <grid-line> ]?
初始值 auto
应用于 网格项 和以 网格容器 为包含块的绝对定位框。
可继承
百分比 不适用
计算值 见各个属性
动画类型 离散 (discrete)
规范顺序 按语法

grid-rowgrid-column 属性分别是 grid-row-start/grid-row-endgrid-column-start/grid-column-end 的简写。

如果指定了两个 <grid-line> 值,则 grid-row-start/grid-column-start 长属性被设置为斜杠前的值,而 grid-row-end/grid-column-end 长属性被设置为斜杠后的值。

当省略第二个值时,如果第一个值是 <custom-ident>,则 grid-row-end/grid-column-end 长属性也被设置为该 <custom-ident>;否则,将其设置为 auto

名称grid-area
<grid-line> [ / <grid-line> ]{0,3}
初始值 auto
应用于 网格项 和以 网格容器 为包含块的绝对定位框。
可继承
百分比 不适用
计算值 见各个属性
动画类型 离散 (discrete)
规范顺序 按语法

grid-area 属性是 grid-row-startgrid-column-startgrid-row-endgrid-column-end 的简写属性。

如果指定了四个 <grid-line> 值,则 grid-row-start 设置为第一个值,grid-column-start 设置为第二个值,grid-row-end 设置为第三个值,grid-column-end 设置为第四个值。

当省略 grid-column-end 时,如果 grid-column-start 是一个 <custom-ident>grid-column-end 设置为该 <custom-ident>;否则,将其设置为 auto

当省略 grid-row-end 时,如果 grid-row-start 是一个 <custom-ident>grid-row-end 设置为该 <custom-ident>;否则,将其设置为 auto

当省略 grid-column-start 时,如果 grid-row-start 是一个 <custom-ident>,则所有四个长属性都设置为该值。否则,将其设置为 auto

注意: 此简写属性的解析顺序为 行起始/列起始/行结束/列结束,这对于 LTR 页面是 逆时针 的,与使用物理方向(如 margin)的相关 4 边缘属性的方向相反。

8.5. 网格项放置算法

以下的 网格项放置算法自动位置网格项 解析为 确定性位置,确保每个 网格项 都有一个定义明确的 网格区域 以便进行布局。(网格跨度 无需特殊解析;如果未显式指定,它们默认为 1。)

注意: 如果在 显式网格 中没有空间来放置自动定位的 网格项,此算法可能导致在 隐式网格 中创建新的行或列。

每个 网格单元(在 显式隐式网格 中)都可以是 已占用 (occupied)未占用 (unoccupied)。如果一个单元格被具有 确定性网格位置网格项网格区域 覆盖,则该单元格被视为 已占用;否则,该单元格为 未占用。单元格的 已占用/未占用 状态可以在此算法执行过程中更改。

为清晰起见,此算法编写时假设指定了 grid-auto-flowrow。如果将其设置为 column,则在此算法中交换所有关于行和列、内联 (inline) 和块 (block) 等的提及。

注意: 自动放置算法 使用 修正后的文档顺序 处理 网格项,而不是它们的原始文档顺序。

  1. 生成匿名网格项,如 § 6 网格项 中所述。(匿名 网格项 总是自动放置的,因为它们的框不能指定任何 网格放置属性。)

  2. 定位所有非自动定位的项。

  3. 处理锁定到给定行的项。

    对于每个具有 确定性行位置网格项(即 grid-row-startgrid-row-end 属性定义了一个 确定性网格位置),按 修正后的文档顺序 处理:

    “稀疏 (sparse)”打包(默认行为)

    将其 放置位置 的列起始线设置为最早(最小正索引)的线索引,确保此项的 网格区域 不会与任何 已占用 网格单元重叠,并且位于此步骤中之前在此行中放置的任何 网格项 之后。

    “密集 (dense)”打包(指定了 dense

    将其 放置位置 的列起始线设置为最早(最小正索引)的线索引,确保此项的 网格区域 不会与任何 已占用 网格单元重叠。

  4. 确定隐式网格中的列。

    隐式网格 中创建列。

    1. 显式网格 的列开始。

    2. 在所有具有 确定性列位置 的项(显式定位的项、上一步中定位的项,以及尚未定位但具有确定性列的项)中,根据需要向 隐式网格 的开头和结尾添加列,以容纳这些项。

    3. 如果所有 没有 确定性列位置 的项中,最大的 列跨度 大于 隐式网格 的宽度,则向 隐式网格 的结尾添加列,以容纳该 列跨度

    例如,在以下样式片段中
    #grid {
      display: grid;
      grid-template-columns: repeat(5, 100px);
      grid-auto-flow: row;
    }
    #grid-item {
      grid-column: 4 / span 3;
    }
    

    所需列数为 6。显式网格 提供了 5 列(来自 grid-template-columns),线编号为 1 到 6,但 #grid-item 的列位置意味着它在第 7 线结束,这需要向 隐式网格 的末尾额外添加一列。

  5. 定位剩余的网格项。

    自动放置光标 定义了网格中的当前“插入点”,指定为一对行和列 网格线。最初,自动放置光标 被设置为 隐式网格 中最起始的行和列线。

    正在使用的 grid-auto-flow 值决定了如何定位这些项。

    “稀疏 (sparse)”打包(默认行为)

    对于每个尚未在上一步中定位的 网格项,按 修正后的文档顺序 处理:

    如果该项具有 确定性列位置
    1. 光标 的列位置设置为 网格项 的列起始线。如果这小于 光标 的先前列位置,则将行位置增加 1。

    2. 增加 光标 的行位置,直到找到一个值,使得 网格项 不会与任何 已占用 网格单元重叠(必要时在 隐式网格 中创建新行)。

    3. 将该项的行起始线设置为 光标 的行位置,并根据其从该位置的跨度设置该项的行结束线。

    如果该项在两个轴上都具有 自动网格位置
    1. 增加 自动放置光标 的列位置,直到该项的 网格区域 不与任何 已占用 网格单元重叠,或者 光标 的列位置加上该项的列跨度超过了隐式网格中的列数(如该算法早期所确定)。

    2. 如果在上一步中找到了非重叠位置,将该项的行起始和列起始线设置为 光标 的位置。否则,增加 自动放置光标 的行位置(必要时在 隐式网格 中创建新行),将其列位置重置为 隐式网格 中最起始的列线,并返回上一步。

    “密集 (dense)”打包(指定了 dense

    对于每个尚未在上一步中定位的 网格项,按 修正后的文档顺序 处理:

    如果该项具有 确定性列位置
    1. 将光标的行位置设置为 隐式网格 中最起始的行线。将光标的列位置设置为 网格项 的列起始线。

    2. 增加 自动放置光标 的行位置,直到找到一个值,使得 网格项 不会与任何 已占用 网格单元重叠(必要时在 隐式网格 中创建新行)。

    3. 将该项的行起始线索引设置为 光标 的行位置。(同时也根据跨度隐含地设置了该项的行结束线。)

    如果该项在两个轴上都具有 自动网格位置
    1. 将光标的行和列位置设置为 隐式网格 中最起始的行和列线。

    2. 增加 自动放置光标 的列位置,直到该项的 网格区域 不与任何 已占用 网格单元重叠,或者 光标 的列位置加上该项的列跨度超过了隐式网格中的列数(如该算法早期所确定)。

    3. 如果在上一步中找到了非重叠位置,将该项的行起始和列起始线设置为 光标 的位置。否则,增加 自动放置光标 的行位置(必要时在 隐式网格 中创建新行),将其列位置重置为 隐式网格 中最起始的列线,并返回上一步。

9. 绝对定位 (Absolute Positioning)

9.1. 以网格容器为包含块

如果绝对定位元素的 包含块 是由 网格容器 生成的,则该包含块对应于由其 网格放置属性 决定的 网格区域。偏移属性(top/right/bottom/left)随后表示从该 包含块 的相应边缘向内的偏移,这与常规情况相同。

注意: 虽然将绝对定位的元素定位到 网格容器 确实允许它与该容器的 网格线 对齐,但此类元素不占用空间,也不以其他方式参与网格的布局。

.grid {
  grid: 1fr 1fr 1fr 1fr / 10rem 10rem 10rem 10rem;
  /* 4 equal-height rows filling the grid container,
     4 columns of ''10rem'' each */
  justify-content: center;
  /* center the grid horizontally within the grid container */
  position: relative;
  /* Establish abspos containing block */
}

.abspos {
  grid-row-start: 1;     /* 1st grid row line = top of grid container */
  grid-row-end: span 2;  /* 3rd grid row line */
  grid-column-start: 3;  /* 3rd grid col line */
  grid-column-end: auto; /* right padding edge */
  /* Containing block covers the top right quadrant of the grid container */

  position: absolute;
  top: 70px;
  bottom: 40px;
  left: 100px;
  right: 30px;
}

注意: 网格和 网格放置属性流相对 (flow-relative) 的,而偏移属性(leftrighttopbottom)是 物理 (physical) 的,因此如果 directionwriting-mode 属性发生变化,网格将转换以匹配,但偏移量不会。

而不是自动放置,网格放置属性auto 值会为 放置位置 贡献一条特殊的线,其位置是 网格容器 的对应填充边缘(如果 网格容器 溢出,则为可滚动区域的填充边缘)。这些线成为用于定位绝对定位项的 增强网格 (augmented grid) 的第一条和最后一条线(第 0 条和第 -0 条)。

注意: 因此,默认情况下,绝对定位框的 包含块 将对应于 网格容器 的填充边缘,就像它对于 块容器 一样。

绝对定位发生在 网格 及其 流内 (in-flow) 内容布局之后,并且不会影响任何网格轨道的大小,也不会以任何方式影响网格的大小/配置。如果一个 网格放置属性 引用了一条不存在的线(无论是显式指定了这样的线,还是通过跨越到现有的 隐式网格 之外),它都会被视为指定了 auto(而不是创建新的 隐式网格线)。

注意: 记住隐式线被假定具有所有线条名称,因此即使一条引用的线未被显式命名,它也可能存在。

如果 放置位置 仅包含一个 网格跨度,则在该轴上用两条 auto 线替换它。(当一个轴上的两个 网格放置属性 最初都贡献了一个跨度,并且 § 8.3.1 网格放置冲突处理 导致第二个跨度被忽略时,会发生这种情况。)

9.2. 以网格容器为父元素

网格容器 的绝对定位子元素是 流外 (out-of-flow) 的,不是 网格项,因此不会影响其他项的放置或网格的大小。

网格容器 的绝对定位子元素的 静态位置 (static position) [CSS2] 的确定方式,就像它是其边缘与 网格容器 的内容边缘重合的 网格区域 中唯一的网格项一样。

注意: 请注意,此位置受子元素上 justify-selfalign-self 值的影响,并且与大多数其他布局模型一样,绝对定位的子元素对包含块的大小或其内容的布局没有影响。

10. 对齐与间距 (Alignment and Spacing)

网格容器网格轨道 确定大小,且所有 网格项 的维度最终确定后,网格项 可以在其 网格区域 内进行对齐。

margin 属性可用于以类似于块布局中 margin 的方式对齐项目。网格项 也遵循 CSS 盒对齐模块 中的 盒对齐属性 [CSS-ALIGN-3],这允许在行和列中基于关键字轻松对齐项目。

默认情况下,网格项 会拉伸以填满其 网格区域。但是,如果 justify-selfalign-self 计算出的值不是 stretch,或者 margin 为 auto,则 网格项 将自动调整大小以适应其内容。

10.1. 间距 (Gutters):row-gapcolumn-gapgap 属性

当在 网格容器 上指定时,row-gapcolumn-gap 属性(及其 gap 简写)定义了 网格行网格列 之间的 间距 (gutters)。它们的语法在 CSS 盒对齐 3 § 8 盒之间的间距 中定义。

这些属性的效果就好像受影响的 网格线 获得了厚度:两条 网格线 之间的 网格轨道 是代表它们的 间距 之间的空间。为了 轨道大小计算 的目的,每个 间距 被视为指定大小的额外、空、固定大小的轨道,该轨道被任何跨越其对应 网格线网格项 所跨越。

注意: 由于 justify-content/align-content,轨道之间可能会添加额外的间距。见 § 11.1 网格大小计算算法。此空间有效地增加了 间距 的大小。

如果 网格 在轨道之间被 分割 (fragmented),则这些轨道之间的 间距 必须被抑制。注意,不同于 margin,即使在强制中断后,间距也会被抑制。

间距 仅出现在 隐式网格 的轨道 之间;在第一条轨道之前或最后一条轨道之后没有间距。(特别是,在 隐式网格 的第一条/最后一条轨道与 增强网格 中的“自动”线之间没有 间距。)

折叠轨道 的间距 发生塌陷 (collapse) 时,它们正好重合——两个间距重叠,使得它们的起始和结束边缘重合。如果 折叠 轨道的一侧没有间距(例如,如果它是 隐式网格 的第一条或最后一条轨道),那么折叠其间距会导致 折叠轨道 的任何“一侧”都没有间距。

10.2. auto margin 对齐

网格项 上的 Auto margin 的作用与 块布局 中的 auto margin 非常相似。

10.3. 内联轴对齐:justify-selfjustify-items 属性

网格项 可以通过在 网格项 上使用 justify-self 属性,或在 网格容器 上使用 justify-items 属性,在内联维度上进行对齐,如 [CSS-ALIGN-3] 中所定义。

例如,对于英文文档,内联轴是水平的,因此 justify-* 属性水平对齐 网格项

如果在一个基线对齐轴向上,其尺寸取决于某个固有尺寸轨道(该轨道尺寸反过来又依赖于该网格项的尺寸和基线对齐,从而形成循环依赖)的网格项上指定了基线对齐,则该项不参与基线对齐,而是使用其回退对齐,就好像该回退对齐是最初指定的一样。为此,当网格容器在相关轴向上具有不确定尺寸时,<flex> 轨道尺寸将被视为“固有尺寸”。

注:是否使用回退对齐在布局过程中不会改变:如果存在循环,它就一直存在。

10.4. 块轴对齐:align-selfalign-items 属性

网格项也可以通过在网格项上使用 align-self 属性,或在网格容器上使用 align-items 属性,在块维度(垂直于行内维度)上进行对齐,如 [CSS-ALIGN-3] 中所定义。

如果在一个网格项上指定了基线对齐,且该项在该轴向上的尺寸取决于某个固有尺寸轨道的尺寸(该轨道尺寸因此依赖于该项的尺寸和基线对齐,从而形成循环依赖),则该项不参与基线对齐,而是使用其回退对齐,就好像该回退对齐是最初指定的一样。为此,当网格容器在相关轴向上具有不确定尺寸时,<flex> 轨道尺寸将被视为“固有尺寸”。

10.5. 网格对齐:justify-contentalign-content 属性

如果网格的外边缘不对应于网格容器的内容边缘(例如,如果没有列是伸缩尺寸的),则网格轨道将根据网格容器上的 justify-contentalign-content 属性在内容框内进行对齐。

例如,以下网格在垂直方向居中,并对齐到其网格容器的右边缘。
.grid {
  display: grid;
  grid: 12rem 12rem 12rem 12rem / 10rem 10rem 10rem 10rem;
  justify-content: end;
  align-content: center;
  min-height: 60rem;
}

如果没有网格轨道显式网格为空,且隐式网格中没有创建轨道),则每个轴上的唯一网格线将与网格容器的起始边缘对齐。

注意,justify-contentalign-content 的某些值可能会导致轨道间隔开(space-around, space-between, space-evenly)或被重新调整尺寸(stretch)。如果网格在轨道之间被分段,则必须抑制这些轨道之间的任何此类额外间距。

例如,在以下网格中,跨度项的网格区域增大,以容纳因对齐分配给间隙的额外空间。.wrapper { display: grid; /* 3-row / 4-column grid container */ grid: repeat(3, auto) / repeat(4, auto); gap: 10px; align-content: space-around; justify-content: space-between; } .item1 { grid-column: 1 / 5; } .item2 { grid-column: 1 / 3; grid-row: 2 / 4; } .item3 { grid-column: 3 / 5; } /* last two items auto-place into the last two grid cells */
Grid with 10px gap and an element spanning all columns.
			          The sum of the columns is less than the width of the grid container.
对齐前的网格
Same grid with increased gaps absorbing the excess grid container width.
			          The spanning element has grown to accommodate the extra space assigned to the gap it crosses.
对齐后的网格

注意,对齐(与 gap 间距不同)发生在网格轨道尺寸确定之后,因此如果轨道尺寸由跨度项的内容决定,它将在对齐阶段获得额外空间以容纳对齐间距。

10.6. 网格容器基线

一个网格容器的第一个(最后一个)基线确定如下:

  1. 查找网格容器中包含至少一个网格项的第一个(最后一个)行。

    如果与该行相交的任何网格项在该行中参与基线对齐,则该网格容器的基线集将根据这些网格项的共享对齐基线生成

    否则,网格容器的第一个(最后一个)基线集将根据行优先网格顺序(根据网格容器书写模式)中第一个(最后一个)网格项对齐基线生成。如果该网格项在网格的行内轴上没有对齐基线,则首先根据其边框边缘合成一个。

  2. 如果网格容器不包含任何网格项,则该网格容器没有第一个(最后一个)基线集,如果需要,根据其对齐上下文的规则合成一个。退出此算法。

网格修改后的文档顺序(网格顺序)是遍历网格的网格单元时遇到网格项的顺序。如果同时遇到两个项,则按顺序修改后的文档顺序获取它们。

当根据上述规则计算基线时,如果贡献基线的框具有允许滚动的overflow值,则为了确定其基线,必须将该框视为处于其初始滚动位置。

确定表格单元格的基线时,网格容器提供基线的方式与行框或表格行相同。[CSS2]

有关基线的更多信息,请参见 CSS 写作模式 3 § 4.1 基线简介CSS 盒对齐 3 § 9 基线对齐细节

11. 网格布局算法

本节定义了网格布局算法,该算法对网格容器进行尺寸调整,确定所有网格轨道的尺寸和位置,并布局已放置到其网格区域中的网格项

  1. 运行网格项放置算法来解析网格中所有网格项的放置。

  2. 根据§ 5.2 网格容器尺寸调整找到网格容器的尺寸。

    注:在此阶段,轨道尺寸中的循环<percentage>被视为 auto

  3. 给定生成的网格容器尺寸,运行网格尺寸调整算法来调整网格尺寸。

    注:在此阶段,轨道尺寸中的<percentage>根据网格容器尺寸进行解析。

  4. 网格项布局到它们各自的包含块中。为此,每个网格区域的宽度和高度被认为是确定的

    注:由于仅使用确定尺寸计算的公式(如拉伸拟合公式)也是确定的,因此被拉伸的网格项的尺寸也被认为是确定的。

11.1. 网格尺寸调整算法

本节定义了网格尺寸调整算法,它决定所有网格轨道及延伸开来的整个网格的尺寸。

每个轨道都有指定的最小最大尺寸函数(可能相同)。每个尺寸函数要么是:

网格尺寸调整算法定义了如何将这些尺寸约束解析为使用的轨道尺寸。

  1. 首先,轨道尺寸调整算法用于解析网格列的尺寸。如果在此步骤中计算网格项的布局取决于块轴上的可用空间,请假设该可用空间为:如果有任何行具有确定最大轨道尺寸函数,则该行具有该尺寸,所有其他行均为无限。如果网格容器和所有轨道都具有确定的尺寸,同时应用 align-content 来查找此类项跨越的任何间隙的最终有效尺寸;否则在此估计中忽略轨道对齐的影响。
    是否有启发式方法可以尝试更准确的初始估计?例如,假设其可用空间为以下各项的最大值:
  2. 它跨越的所有确定轨道尺寸之和(使用轨道的最小和最大尺寸函数中的最大值,如果两者都是确定的,则使用 fit-content() 的参数(如果它是确定的))。
  3. 该项的 min-content 尺寸(如果它跨越的任何轨道具有 min-contentfit-content() 尺寸函数)。
  4. 该项的 自动最小尺寸(如果它跨越的任何轨道具有 auto 最小尺寸函数)。
  5. 无限(如果它跨越的任何轨道具有 max-content 最小尺寸函数,或者 max-contentauto<flex> 最大尺寸函数)。

    这或许可以减少所需的重新布局次数,但在任何情况下是否会产生不同或更好的结果?我们是否应该将其采纳到规范中?

  6. 接下来,轨道尺寸调整算法解析网格行的尺寸。要找到任何其块轴尺寸贡献需要它的项的行内轴可用空间,请使用上一步中计算的网格列尺寸。如果网格容器行内尺寸确定的,同时应用 justify-content 来考虑有效的列间隙尺寸。
  7. 然后,如果任何网格项的 min-content 贡献根据步骤 2 中计算的行尺寸和对齐方式发生了变化,请使用新的 min-contentmax-content 贡献重新解析网格列的尺寸(仅限一次)。要找到任何其行内轴尺寸贡献需要它的项的块轴可用空间,请使用上一步中计算的网格行尺寸。如果网格容器块尺寸确定的,同时应用 align-content 来考虑有效的行间隙尺寸。
    这种重复对于网格项行内尺寸取决于其网格区域块尺寸的情况是必要的。示例包括换行的列伸缩容器flex-flow: column wrap)、正交流writing-mode)、多列容器以及尺寸取决于行尺寸的具有长宽比的项(或其子项具有长宽比)。
  8. 接下来,如果任何网格项的 min-content 贡献根据步骤 3 中计算的列尺寸和对齐方式发生了变化,请使用新的 min-contentmax-content 贡献重新解析网格行的尺寸(仅限一次)。要找到任何其块轴尺寸贡献需要它的项的行内轴可用空间,请使用上一步中计算的网格列尺寸。如果网格容器行内尺寸确定的,同时应用 justify-content 来考虑有效的列间隙尺寸。
  9. 最后,根据 align-contentjustify-content 属性在网格容器内对齐轨道。注:这可能会在轨道之间引入额外空间,从而可能将跨越间隙的任何网格项的网格区域扩大到超出轨道尺寸调整期间分配给它的空间。

11.2. 轨道尺寸调整术语

最小轨道尺寸计算函数
如果轨道使用 minmax() 函数调整尺寸,这是该函数的第一个参数。如果轨道使用 <flex> 值或 fit-content() 函数调整尺寸,则为 auto。否则,为轨道的尺寸函数。
最大轨道尺寸计算函数
如果轨道使用 minmax() 函数调整尺寸,这是该函数的第二个参数。否则,为轨道的尺寸函数。在所有情况下,将 autofit-content() 视为 max-content,除非为 fit-content() 另有说明。
可用网格空间
在每个维度中独立地,可用网格空间是:
  • 如果网格容器的尺寸是确定的,则使用其内容框的尺寸。

  • 如果网格容器正在min-content 约束max-content 约束下调整尺寸,则可用网格空间就是该约束(且是不确定的)。

  • 注:表示基于内容的尺寸调整的 auto 尺寸(例如水平书写模式下块级框的高度)等同于 max-content

    在所有情况下,如果网格容器的最小/最大宽度/高度属性是确定的,请根据这些属性限制可用网格空间

    自由空间
    等于可用网格空间减去所有网格轨道(包括间隙)的基准尺寸之和,以零为下限。如果可用网格空间不确定的,则剩余空间不确定
    跨度计数
    网格项在适用维度中跨越的网格轨道数量。

    注:请记住,为了网格尺寸调整算法的目的,间隙被视为固定尺寸轨道——即最小和最大尺寸函数都设置为间隙已用尺寸的轨道。它们的宽度需要相应地纳入轨道尺寸调整算法的计算中。

    11.3. 轨道尺寸调整算法

    本节的其余部分是轨道尺寸调整算法,它根据最小最大轨道尺寸函数计算已用轨道尺寸。每个轨道都有一个基准尺寸(一个在算法过程中不断增长并最终成为轨道最终尺寸的 <length>)和一个增长限制(一个为基准尺寸提供期望最大尺寸的 <length>)。分为 5 个步骤:

    1. 初始化轨道尺寸
    2. 解析固有轨道尺寸
    3. 最大化轨道
    4. 扩展伸缩轨道
    5. 扩展拉伸的 auto 轨道

    11.4. 初始化轨道尺寸

    初始化每个轨道的基准尺寸和增长限制。对于每个轨道,如果轨道的最小轨道尺寸函数是:

    一个固定尺寸函数
    解析为绝对长度,并将该尺寸用作轨道的初始基准尺寸注:不确定长度不会出现,因为它们被视为 auto
    一个固有尺寸函数
    使用初始基准尺寸为零。

    对于每个轨道,如果轨道的最大轨道尺寸函数是:

    一个固定尺寸函数
    解析为绝对长度,并将该尺寸用作轨道的初始增长限制
    一个固有尺寸函数
    一个伸缩尺寸函数
    使用初始增长限制为无穷大。

    在所有情况下,如果增长限制小于基准尺寸,则增加增长限制以匹配基准尺寸

    注:为了轨道尺寸调整算法的目的,间隙被视为空的固定尺寸轨道。

    11.5. 解析固有轨道尺寸

    此步骤将固有轨道尺寸函数解析为绝对长度。首先,它根据完全包含在单个轨道内的项来解析这些尺寸。然后,它逐渐增加跨越多个轨道的项的空间需求,尽可能地在这些轨道之间均匀分配额外空间。

    注:当此步骤完成时,所有固有基准尺寸增长限制都已解析为绝对长度。

    注:记住 fit-content()auto 最大轨道尺寸函数被视为与 max-content 相同,除非另有明确说明。

    1. 对基线对齐的项进行填充(Shim),使其固有尺寸贡献反映其基线对齐。对于每个基线共享组中的项,在每个项的起始/结束侧(针对第一个/最后一个基线对齐)添加一个“填充”(实际上是额外的外边距),以便在进行起始/结束对齐时,它们的基线按规定对齐在下方的轨道尺寸调整中,将这些“填充”视为项的固有尺寸贡献的一部分。如果一个项使用多个固有尺寸贡献,它可以为每个贡献拥有不同的填充。
      例如,当网格容器具有不确定尺寸时,它首先在 min/max-content 约束下布局以找到尺寸,然后以该尺寸“真正”布局(这可能会影响百分比轨道等)。为每个阶段添加的“填充”是独立的,并且仅影响该阶段的布局。

      注:注意基线自对齐基线内容对齐的项在此步骤中都会被考虑。

      注:由于自身尺寸取决于固有尺寸轨道尺寸的网格项不参与基线对齐,因此它们不会被填充。

    2. 调整轨道尺寸以适应不跨越的项:对于每个具有固有轨道尺寸函数且没有伸缩尺寸函数的轨道,考虑其中跨度为 1 的项:
      针对 min-content 最小值:
      如果轨道具有 min-content 最小轨道尺寸函数,则将其基准尺寸设置为项的 min-content 贡献的最大值,以零为下限。
      针对 max-content 最小值:
      如果轨道具有 max-content 最小轨道尺寸函数,则将其基准尺寸设置为项的 max-content 贡献的最大值,以零为下限。
      针对 auto 最小值:
      如果轨道具有 auto 最小轨道尺寸函数,并且网格容器正在min-/max-content 约束下调整尺寸,则将轨道的基准尺寸设置为项的 受限 min-content 贡献的最大值,以零为下限。项的受限 min-/max-content 贡献(为此目的)是其 min-/max-content 贡献(相应地),受到最大轨道尺寸函数(可能是 fit-content() 轨道尺寸函数的参数)的限制(如果它是固定的),并最终以其最小贡献(定义如下)为下限。否则,将轨道的基准尺寸设置为项的最小贡献的最大值,以零为下限。项的最小贡献是其可能具有的最小外部尺寸。具体而言,如果项的计算出的首选尺寸表现为 auto,或者在相关轴上取决于其包含块的尺寸,则其最小贡献是假设项的已用最小尺寸作为其首选尺寸而产生的外部尺寸;否则项的最小贡献是其 min-content 贡献。因为最小贡献通常取决于项的内容尺寸,所以它被视为一种固有尺寸贡献

      注:对于指定最小尺寸为 auto(初始值)的项,最小贡献通常等同于 min-content 贡献,但在某些情况下可能有所不同,参见 § 6.6 网格项的自动最小尺寸。此外,最小贡献min-content 贡献max-content 贡献

      针对 min-content 最大值:
      如果轨道具有 min-content 最大轨道尺寸函数,则将其增长限制设置为项的 min-content 贡献的最大值。
      针对 max-content 最大值:
      如果轨道具有 max-content 最大轨道尺寸函数,则将其增长限制设置为项的 max-content 贡献的最大值。对于 fit-content() 最大值,此外还要根据 fit-content() 参数限制此增长限制

      在所有情况下,如果轨道的增长限制现在小于其基准尺寸,则增加增长限制以匹配基准尺寸

      注:此步骤是下文中用于处理跨度项的步骤的简化,对于跨度为 1 的项,其结果应与运行那些指令的行为相同。

    3. 增加尺寸以适应跨越固有尺寸轨道的跨度项:接下来,考虑跨度为 2 且不跨越具有伸缩尺寸函数的轨道的项。
    4. 针对固有最小值:首先分配额外空间给具有固有最小轨道尺寸函数的轨道的基准尺寸,以适应这些项的最小贡献如果网格容器正在min-max-content 约束下调整尺寸,请在此处使用项的受限 min-content 贡献代替其最小贡献。(对于跨越多个轨道的项,计算其受限 min-/max-content 贡献时使用的上限是其跨越的任何固定最大轨道尺寸函数总和,且仅在它仅跨越此类轨道时应用。)
    5. 针对基于内容的最小值:接下来继续分配额外空间给具有 min-contentmax-content 最小轨道尺寸函数的轨道的基准尺寸,以适应这些项的 min-content 贡献
    6. 针对 max-content 最小值:接下来,如果网格容器正在max-content 约束下调整尺寸,请继续分配额外空间给具有 automax-content 最小轨道尺寸函数的轨道的基准尺寸,以适应这些项的受限 max-content 贡献在所有情况下,继续分配额外空间给具有 max-content 最小轨道尺寸函数的轨道的基准尺寸,以适应这些项的 max-content 贡献
    7. 如果此时任何轨道的增长限制现在小于其基准尺寸,则增加其增长限制以匹配其基准尺寸
    8. 针对固有最大值:接下来分配额外空间给具有固有最大轨道尺寸函数的轨道的增长限制,以适应这些项的 min-content 贡献。在下一步中,将任何增长限制从无限变为有限的轨道标记为无限可增长 为什么要存在无限可增长标记?

      Peter Salas 解释道::

      Consider the following case:
      
      Two "auto" tracks (i.e. ''minmax(min-content, max-content) minmax(min-content, max-content)'').
      Item 1 is in track 1, and has min-content = max-content = 10.
      Item 2 spans tracks 1 and 2, and has min-content = 30, max-content = 100.
      
      After resolving min-content/max-content for the first item, we have this.
      
      track 1: base size = 10 growth limit = 10
      
      track 2: base size = 0 growth limit = infinity
      
      Then we resolve min-content/max-content for the second item.
      
      Phase 1 sets the base size of track 2 to 20 so that the two tracks' base sizes sum to 30.
      Phase 2 does nothing because there are no relevant tracks.
      Phase 3 sets the growth limit of track 2 to 20 so that the two tracks' growth limits sum to 30.
      In phase 4, we need to grow the sum of the growth limits by 70 to accommodate item 2.
      Two options are:
      
      1. Grow each track’s growth limit equally,
        and end up with growth limits = [45, 55].
      2. Grow only the second track’s growth limit,
        and end up with growth limits = [10, 90].
      
      By not considering the just-set growth limit as a constraint during space distribution
      (i.e. by treating it as infinity),
      we get the second result,
      which we considered a better result because the first track remains sized exactly to the first item.
      
    9. 针对 max-content 最大值:最后继续分配额外空间给具有 max-content 最大轨道尺寸函数的轨道的增长限制,以适应这些项的 max-content 贡献

    对跨度更大的项递增重复上述过程,直到所有项都被考虑。

  • 增加尺寸以适应跨越伸缩轨道的跨度项:接下来,重复上一步,但(作为一个整体,而不是按跨度大小分组)考虑所有确实跨越具有伸缩尺寸函数的轨道的项,同时:
  • 将空间分配给伸缩轨道(即,将所有其他轨道视为具有固定尺寸函数);
  • 如果该项跨越的所有伸缩轨道伸缩尺寸函数之和大于或等于 1,则根据其伸缩尺寸函数的比例而不是平均分配空间给这些轨道;如果总和小于 1,则根据其伸缩尺寸函数的比例分配该比例的空间,其余部分平均分配。
  • 如果任何轨道仍然具有无限的增长限制(例如因为它其中没有放置任何项,或者它是一个伸缩轨道),则将其增长限制设置为其基准尺寸

    注:当项跨越多个轨道时,没有单一的方法可以满足固有尺寸约束。该算法体现了许多在实际用例中已被证明能提供良好结果的启发式方法,例如本规范前面的“游戏”示例。该算法未来可能会更新,以在确定更先进的启发式方法时将其纳入考量。

    11.5.1. 在跨越的轨道之间分配额外空间

    分配额外空间,请执行以下步骤,使用以下输入:
  • 是否影响基准尺寸增长限制受影响尺寸)。

  • 哪些轨道受到影响(受影响轨道)。

  • 正在适应哪些固有尺寸贡献(尺寸贡献),以及跨越这些轨道的哪些网格项()。

    1. 分别为每个受影响轨道维护一个计划增量,初始设置为 0。(这防止了尺寸增加变得依赖于顺序。)
    2. 对于每个被适应的,仅考虑该项跨越的轨道:
    3. 查找要分配的空间:从项的尺寸贡献中减去每个跨越轨道(不仅仅是受影响轨道)的受影响尺寸,以零为下限。(对于无限的增长限制,替换为轨道的基准尺寸。)此剩余尺寸贡献即为要分配的空间space = max(0, size contribution - ∑track-sizes)
    4. 在限度内分配空间

      通过以下方式为每个受影响轨道找到项引起的增量:将空间平均分配给这些轨道,当轨道的受影响尺寸 + 项引起的增量达到其限度时冻结轨道的项引起的增量(并根据需要继续增长未冻结的轨道)。

      对于基准尺寸限度是其增长限制,如果存在,则由其 fit-content() 参数设定上限。对于增长限制,如果增长限制是有限的且轨道未被标记为无限可增长,则限度增长限制;否则,如果它具有 fit-content() 轨道尺寸函数,则为该 fit-content() 参数,否则为无穷大。

      注:如果受影响尺寸增长限制且轨道未标记为无限可增长,则每个项引起的增量将为零。

    5. 分配空间给未受影响的轨道:

      如果此时仍有额外的空间剩余,并且该项同时跨越受影响轨道和非受影响轨道,请像上一步一样分配空间,但改为分配给非受影响轨道

      注:这将任何剩余空间分配给尚未达到其增长限制的轨道,而不是违反受影响轨道的增长限制。

    6. 在限度外分配空间

      如果此时仍有额外的空间剩余,则解冻并继续将空间分配给以下轨道的项引起的增量……

      为此,fit-content() 轨道的最大轨道尺寸函数在轨道达到指定为 fit-content() 参数的限制之前被视为 max-content,之后其最大轨道尺寸函数被视为该参数的固定尺寸函数(这会改变在此步骤中继续获得空间的轨道)。

      注:此步骤根据轨道的最大轨道尺寸函数类型,优先分配用于适应超出轨道当前增长限制的尺寸贡献的空间。

    7. 对于每个受影响轨道,如果轨道的项引起的增量大于轨道的计划增量,则将轨道的计划增量设置为该值。
  • 更新轨道的受影响尺寸,加上计划增量,以便下一轮空间分配将考虑该增量。(如果受影响尺寸是无限的增长限制,则将其设置为轨道的基准尺寸加上计划增量。)

    11.6. 最大化轨道

    如果剩余空间为正,将其平均分配给所有轨道的基准尺寸,当轨道达到其增长限制时冻结轨道(并根据需要继续增长未冻结的轨道)。

    为了此步骤的目的:如果在 max-content 约束下调整网格容器的尺寸,则剩余空间是无限的;如果在 min-content 约束下调整,则剩余空间为零。

    如果这将导致网格大于受其max-width/height限制的网格容器内部尺寸,则重做此步骤,将可用网格空间视为等于网格容器处于其max-width/height时的内部尺寸

    11.7. 扩展伸缩轨道

    此步骤使用可以在不超过可用空间的情况下分配给 fr 的最大值来调整伸缩轨道的尺寸。

    首先,找到网格的已用伸缩分数

    如果剩余空间为零,或者在 min-content 约束下调整网格容器的尺寸:
    已用伸缩分数为零。
    否则,如果剩余空间是一个确定的长度:
    已用伸缩分数是使用所有网格轨道和作为可用网格空间填充空间查找 fr 的尺寸的结果。
    否则,如果剩余空间是一个不确定的长度:
    已用伸缩分数是以下各项的最大值:
  • 对于每个伸缩轨道,如果伸缩轨道的伸缩因子大于 1,则为该轨道基准尺寸除以其伸缩因子的结果;否则,为该轨道的基准尺寸
  • 对于每个跨越伸缩轨道的网格项,使用该项跨越的所有网格轨道和作为其 max-content 贡献填充空间查找 fr 的尺寸的结果。

    如果使用此伸缩分数会导致网格小于网格容器min-width/height(或大于网格容器max-width/height),则重做此步骤,将剩余空间视为确定的,并将可用网格空间视为等于网格容器处于其 min-width/height (max-width/height) 时的内部尺寸

  • 对于每个伸缩轨道,如果已用伸缩分数与该轨道的伸缩因子的乘积大于该轨道的基准尺寸,则将其基准尺寸设置为该乘积。

    11.7.1. 查找 fr 的尺寸

    此算法查找 fr 单位在不超过目标尺寸的情况下所能达到的最大尺寸。必须使用一组网格轨道和一定量的填充空间来调用它。

    1. 剩余空间填充空间减去非伸缩网格轨道基准尺寸
    2. 伸缩因子总和伸缩轨道伸缩因子之和。如果该值小于 1,则将其设置为 1。
    3. 假设 fr 尺寸剩余空间除以伸缩因子总和
    4. 如果 假设 fr 尺寸弹性轨道伸缩系数 之积小于轨道的基准尺寸,则重启此算法,将所有此类轨道视为非弹性轨道。
    5. 返回 假设 fr 尺寸

    11.8. 拉伸 auto 轨道

    网格容器内容分布属性 在此轴上为 normalstretch 时,此步骤通过将任何剩余的正数、确定性 剩余空间 等分给具有 auto 最大轨道尺寸函数 的轨道来扩展它们。如果 剩余空间不确定性 的,但 网格容器 具有 确定性最小宽度/高度,则改用该尺寸来计算此步骤的 剩余空间

    12. 网格布局的分段

    网格容器 可以在行或列之间以及项目内部跨页断行。 break-* 属性按照其所属格式化上下文的常规方式应用于网格容器。本节定义了这些属性如何应用于网格项目及网格项目的内容。

    以下断行规则将 分段容器 称为“页面”。同样的规则适用于任何其他 分段上下文。(必要时用适当的 分段容器 类型替换“页面”。)请参阅 CSS 分段模块 [CSS3-BREAK]

    分段网格容器的确切布局在这一级网格布局中尚未定义。然而,网格容器内部的断行受以下规则约束:

    • 网格项目 上的 break-beforebreak-after 属性会传播到其网格行。第一行上的 break-before 属性和最后一行上的 break-after 属性会传播到网格容器。
    • 网格项目内部的强制断行实际上会增加其内容的大小;它不会触发同级项目内部的强制断行。
    • A 类断行机会 出现在行或列之间(以适当的轴为准),而 C 类断行机会 出现在第一/最后一行(列)与网格容器的内容边缘之间。 [CSS3-BREAK]
    • 当网格容器在断行后继续时,其 网格项目 可用的空间(在分段上下文的块流方向上)会减去之前页面上网格容器碎片所消耗的空间。网格容器碎片所消耗的空间是其在该页面上的内容框大小。如果此调整导致可用空间变为负值,则将其设为零。
    • 除了前一点所强制要求的项目重排外,用户代理(UA)应尝试最小化网格容器相对于未分段流的失真。

    12.1. 分段算法示例

    本节是非规范性的。

    这是一个可能的分段算法的草稿,仍需与 [CSS-FLEXBOX-1] 算法进行严格的交叉核对以确保一致性。欢迎反馈;请参考上述规则作为实现指南。

    1. 使用 分段容器 的内联尺寸并假设块尺寸无限,按照 § 11 网格布局算法 对网格进行布局。在此步骤中,所有 grid-rowautofr 值必须已解析。
    2. 使用上一步解析出的值来布局网格容器。
    3. 如果 网格区域 的尺寸由于分段而发生变化(在此决定中不包括跨行的项目),则根据需要增加以下网格行的网格行尺寸:
      • 具有基于内容的最小轨道尺寸函数。
      • 位于没有显式高度的网格中,且网格行是弹性的。
    4. 如果网格高度为 auto,则网格的高度应为最终行尺寸的总和。
    5. 如果网格区域因分段期间的外边距折叠而溢出网格容器,则扩展网格容器以包含此网格区域(此步骤对于避免因分段导致的循环布局依赖是必要的)。

    如果指定了网格高度,第三步和第四步可能会导致网格行溢出网格。

    13. 隐私考量

    网格布局不会引入新的隐私泄露。

    14. 安全考量

    网格布局不会引入新的安全考量。

    致谢

    本规范的实现离不开 Erik Anderson、Rachel Andrew、Rossen Atanassov、Oriol Brufau、Manuel Rego Casasnovas、Arron Eicholz、Javier Fernandez、Sylvain Galineau、Markus Mielke、Daniel Holbert、John Jansen、Chris Jones、Kathy Kam、Veljko Miljanic、Charbel Nicolas、Mats Palmgren、François Remy、Sergio Villar Senin、Jen Simmons、Christian Stockwell、Eugene Veselov 以及 CSS 工作组成员的贡献,特别感谢微软的 Rossen Atanassov、Alex Mogilevsky、Phil Cupp 和 Peter Salas 创建了最初的提案。同时也感谢 Eliot Graff 的编辑输入。

    变更 (Changes)

    本节记录了自上次发布以来的变更。

    2020 年 12 月 18 日 CR 版以来的变更

    2020 年 8 月 18 日 CR 版以来的变更

    • 修复了上一版 CR 中引入的错误,该错误源于一次未记录的尝试,即澄清 § 6.2 网格项目尺寸aspect-ratio 之间的交互。
    • 将“固有纵横比”的一些实例更新为使用更通用的术语 首选纵横比。(问题 4962
    • 小的编辑清理,并更好地协调了各规范间的术语。

    2017 年 12 月 15 日 CR 版以来的变更

    提供了一份 评论处理意见

    重大变更

    微小变更

    澄清

    2016 年 9 月 29 日 CR 版以来的变更

    同样提供了一份 评论处理意见

    重大变更

    • 由于缺乏实现且需要进一步讨论,将 subgrid 功能推迟到第 2 级。(问题 958
    • grid 简写属性重置的属性列表中移除了 grid-row-gapgrid-column-gap。(问题 1036
    • 移除了 grid-row-gap, grid-column-gapgrid-gap 属性,替换为现在定义在 CSS 框对齐 中的 row-gap, column-gapgap问题 1696
    • 更改了具有 自然尺寸 的网格项目(如图像)的 自动尺寸调整,以便当对齐属性为 normal(默认情况)时,它们保持其 自然尺寸。(问题 #523)请参阅 § 6.2 网格项目尺寸(对比 原始版本)。
    • 更改了 网格容器 内部 <percentage> 轨道的行为,当网格容器的尺寸依赖于这些轨道的尺寸时,使其符合实现,即通过将尺寸调整为 auto 来贡献其维度,并随后根据产生的 网格容器 尺寸解析百分比,而不是被视为精确的 auto 轨道,或者为了满足百分比而从 auto 尺寸增加其自身及 网格容器 的尺寸以避免溢出。这经常会导致轨道溢出 网格容器,并且当 <percentage> 尺寸在 fit-content 尺寸的 网格容器(如 auto 尺寸的内联或浮动 网格容器)中使用时,轨道的内容会溢出轨道。(为避免此问题,请改用 <flex> 单位,它们旨在保持比例且在网格进行固有尺寸调整时不会溢出。)

      如果 网格容器 的尺寸依赖于其轨道的尺寸,则 <percentage> 必须被视为 auto 以便计算 网格容器 的固有尺寸,然后在布局网格及其项目时根据该尺寸进行解析UA 可以 调整轨道对 网格容器 尺寸的固有尺寸贡献,并通过最小量增加轨道的最终尺寸,从而尊重百分比。

    重大调整与修复

    澄清

  • 一致性

    文档约定

    一致性要求通过描述性断言和 RFC 2119 术语相结合来表达。本文档规范性部分中的关键词“MUST”(必须)、“MUST NOT”(不得)、“REQUIRED”(必需)、“SHALL”(应)、“SHALL NOT”(不应)、“SHOULD”(推荐)、“SHOULD NOT”(不推荐)、“RECOMMENDED”(建议)、“MAY”(可以)和“OPTIONAL”(可选)应按照 RFC 2119 中的描述进行解释。然而,为了可读性,这些词在本文档中不以全大写形式出现。

    本规范的所有文本均为规范性文本,明确标记为非规范性的部分、示例和注释除外。 [RFC2119]

    本规范中的示例均以“例如”一词引入,或者通过 class="example" 与规范性文本隔开,如下所示

    这是一个说明性示例。

    说明性注释以“Note”一词开头,并使用 class="note" 与规范性文本隔开,如下所示

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

    建议(Advisements)是规范性章节,旨在引起特别注意,并使用 <strong class="advisement"> 与其他规范性文本区分开来,如下所示: 用户代理必须提供可访问的替代方案。

    一致性类别

    本规范为三类一致性定义了一致性要求。

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

    如果样式表包含的所有使用本模块定义语法的语句,根据通用 CSS 语法及本模块定义的各功能语法均有效,则该样式表符合本规范。

    如果渲染器除了按相应规范解释样式表外,还通过正确解析本规范定义的所有功能并相应地渲染文档来支持这些功能,则该渲染器符合本规范。然而,由于设备限制导致 UA 无法正确渲染文档,并不意味着该 UA 不符合规范。(例如,UA 无需在单色显示器上渲染颜色。)

    如果创作工具编写的样式表根据通用 CSS 语法及本模块中各功能的语法是句法正确的,并符合本模块中描述的所有其他样式表一致性要求,则该创作工具符合本规范。

    部分实现

    为了使作者能够利用前向兼容的解析规则来指定后备值,CSS 渲染器 **必须** 将其无法使用支持级别的任何 @规则、属性、属性值、关键字和其他语法结构视为无效(并 适当忽略)。特别地,用户代理 **不得** 在单一多值属性声明中选择性地忽略不支持的组件值而保留支持的值:如果任何值被视为无效(因为不支持的值必须如此),CSS 要求忽略整个声明。

    不稳定和专有特性的实现

    为了避免与未来稳定的 CSS 功能发生冲突,CSS 工作组建议在实施不稳定功能和私有扩展遵循最佳实践

    非实验性实现

    一旦规范达到候选推荐阶段,非实验性实现即可成为可能,实现者应发布他们能够证明根据规范正确实现的任何 CR 级别特性的无前缀实现。

    为建立并保持 CSS 在不同实现间的互操作性,CSS 工作组请求非实验性的 CSS 渲染器在发布任何 CSS 功能的无前缀实现之前,向 W3C 提交一份实现报告(并在必要时提交用于该实现报告的测试用例)。提交给 W3C 的测试用例需经 CSS 工作组审阅和修正。

    有关提交测试用例和实现报告的详细信息,请访问 CSS 工作组网站 https://w3org.cn/Style/CSS/Test/。问题可发送至 public-css-testsuite@w3.org 邮件列表。

    候选推荐标准 (CR) 退出标准

    为了使本规范能够推进到提案推荐标准 (PR),必须至少有两个独立的、可互操作的每个功能的实现。每个功能可以由不同组的产品实现,不要求所有功能都由单个产品实现。为了实现此标准,我们定义以下术语

    independent
    每个实现必须由不同的方开发,并且不能共享、重用或派生自另一个合格实现所使用的代码。对本规范实现无影响的代码段不受此要求限制。
    可互操作
    通过官方 CSS 测试套件中的相应测试用例,或者如果实现不是 Web 浏览器,则通过等效测试。如果此类用户代理 (UA) 用于声明互操作性,则测试套件中的每个相关测试都应创建等效测试。此外,如果此类 UA 用于声明互操作性,则必须有一个或多个额外的 UA,它们也可以以相同的方式通过这些等效测试,以实现互操作性的目的。等效测试必须公开,以供同行评审。
    实现
    用户代理,即
    1. 实现了该规范。
    2. 对公众可用。该实现可以是出货产品或其他公开可用的版本(即测试版、预览发布版或“每日构建版”)。非出货产品发布版必须已实现该功能至少一个月,以证明其稳定性。
    3. 不是实验性的(即,专门为通过测试套件设计且不打算用于正常使用的版本)。

    该规范将保持候选推荐标准状态至少六个月。

    索引

    本规范定义的术语

  • 列位置,见 § 8
  • 列跨度,见 § 8
  • 计算重复标记,见 § 7.2.5
  • 计算轨道列表,见 § 7.2.5
  • 计算轨道尺寸,见 § 7.2.5
  • 基于内容的最小尺寸,见 § 6.6
  • 内容尺寸建议,见 § 6.6
  • 光标,见 § 8.5
  • <custom-ident>,见 § 8.3
  • 确定性列位置,见 § 8
  • 确定性列跨度,见 § 8
  • 确定性网格位置,见 § 8
  • 确定性网格跨度,见 § 8
  • 确定性位置,见 § 8
  • 确定性行位置,见 § 8
  • 确定性行跨度,见 § 8
  • 确定性跨度,见 § 8
  • dense,见 § 7.7
  • 分配额外空间,见 § 11.5.1
  • 显式,见 § 7.1
  • 显式网格,见 § 7.1
  • 显式网格列,见 § 7.1
  • 显式网格属性,见 § 7.1
  • 显式网格行,见 § 7.1
  • 显式网格轨道,见 § 7.1
  • 显式分配的行名,见 § 7.2.2
  • <explicit-track-list>,见 § 7.2
  • fit-content(),见 § 7.2.1
  • <fixed-breadth>,见 § 7.2
  • <fixed-repeat>,见 § 7.2.3.1
  • <fixed-size>,见 § 7.2
  • 固定尺寸函数,见 § 11.1
  • <flex>,见 § 7.2.4
  • <flex [0,∞]>,见 § 7.2.1
  • 弹性因子,见 § 7.2.1
  • 弹性因子之和,见 § 11.7.1
  • 弹性分数,见 § 7.2.4
  • 灵活长度,见 § 7.2.4
  • 灵活尺寸函数,见 § 11.1
  • 灵活轨道,见 § 7.2.4
  • fr,见 § 7.2.4
  • 可用空间,见 § 11.2
  • fr 单位,见 § 7.2.4
  • grid
  • 网格区域,见 § 3.3
  • grid-area,见 § 8.4
  • grid-auto-columns,见 § 7.6
  • grid-auto-flow,见 § 7.7
  • grid-auto-rows,见 § 7.6
  • 网格单元,见 § 3.2
  • 网格列,见 § 3
  • grid-column,见 § 8.4
  • grid-column-end,见 § 8.3
  • 网格列线,见 § 3.1
  • grid-column-start,见 § 8.3
  • 网格容器,见 § 5.1
  • 网格格式化上下文,见 § 5.1
  • 网格项,见 § 6
  • 网格项放置算法,见 § 8.5
  • 网格布局,见 § 3
  • 网格布局算法,见 § 10.6
  • 网格级,见 § 6.1
  • <grid-line>,见 § 8.3
  • 网格线,见 § 3.1
  • 网格修改的文档顺序,见 § 10.6
  • 网格顺序,见 § 10.6
  • 网格放置,见 § 8
  • 网格放置属性,见 § 8
  • 网格位置,见 § 8
  • 网格行,见 § 3
  • grid-row,见 § 8.4
  • grid-row-end,见 § 8.3
  • 网格行线,见 § 3.1
  • grid-row-start,见 § 8.3
  • 网格尺寸调整算法,见 § 11
  • 网格跨度,见 § 8
  • grid-template,见 § 7.4
  • grid-template-areas,见 § 7.3
  • grid-template-columns,见 § 7.2
  • grid-template-rows,见 § 7.2
  • <'grid-template-rows'> / [ auto-flow && dense? ] <'grid-auto-columns'>?,见 § 7.8
  • <'grid-template-rows'> / <'grid-template-columns'>,见 § 7.4
  • 网格轨道,见 § 3.2
  • 增长限制,见 § 11.3
  • 假想的 fr 尺寸,见 § 11.7.1
  • 隐式,见 § 7.5
  • 隐式网格,见 § 7.5
  • 隐式网格列,见 § 7.5
  • 隐式网格线,见 § 7.5
  • 隐式网格属性,见 § 7.5
  • 隐式网格行,见 § 7.5
  • 隐式网格轨道,见 § 7.5
  • 隐式分配的行名,见 § 7.3.2
  • 隐式命名的区域,见 § 7.3.3
  • 可无限增长,见 § 11.5
  • <inflexible-breadth>,见 § 7.2
  • inline-grid,见 § 5.1
  • [ <integer [-∞,-1]> | <integer [1,∞]> ] && <custom-ident>?,见 § 8.3
  • 内在尺寸调整函数,见 § 11.1
  • 剩余空间,见 § 11.7.1
  • <length-percentage [0,∞]>,见 § 7.2.1
  • 受限最大内容贡献,见 § 11.5
  • 受限最小内容贡献,见 § 11.5
  • 行名,见 § 7.2.2
  • <line-names>,见 § 7.2
  • 行名集合,见 § 7.2.5
  • [ <line-names>? <string> <track-size>? <line-names>? ]+ [ / <explicit-track-list> ]?,见 § 7.4
  • max-content,见 § 7.2.1
  • 最大轨道尺寸函数,见 § 11.2
  • min-content,见 § 7.2.1
  • 最小贡献,见 § 11.5
  • minmax(),见 § 7.2.1
  • 最小轨道尺寸函数,见 § 11.2
  • 命名单元格标记,见 § 7.3
  • 命名网格区域,见 § 7.3
  • none(无)
  • 空单元格标记,见 § 7.3
  • 已占用,见 § 8.5
  • 放置,见 § 8
  • 位置,见 § 8
  • repeat(),见 § 7.2.3
  • row
  • 行位置,见 § 8
  • 行跨度,见 § 8
  • 尺寸调整函数,见 § 7.2
  • 待填充空间,见 § 11.7.1
  • 跨度,见 § 8
  • 跨度计数,见 § 11.2
  • span && [ <integer [1,∞]> || <custom-ident> ],见 § 8.3
  • 指定尺寸建议,见 § 6.6
  • <string>+,见 § 7.3
  • 轨道,见 § 3.2
  • <track-breadth>,见 § 7.2
  • <track-list>,见 § 7.2
  • 轨道列表,见 § 7.2
  • <track-list> | <auto-track-list>,见 § 7.2
  • <track-repeat>,见 § 7.2.3.1
  • 轨道部分,见 § 7.2.5
  • <track-size>,见 § 7.2
  • 轨道尺寸调整算法,见 § 11.3
  • 轨道尺寸调整函数,见 § 7.2
  • 转换尺寸建议,见 § 6.6
  • 垃圾标记,见 § 7.3
  • 未占用,见 § 8.5
  • 通过引用定义的术语

    引用

    规范性引用

    [CSS-ALIGN-3]
    Elika Etemad; Tab Atkins Jr.. CSS 盒子对齐模块 Level 3. 2025 年 3 月 11 日. 工作草案 (WD). URL: https://w3org.cn/TR/css-align-3/
    [CSS-BOX-4]
    Elika Etemad. CSS 盒模型模块 Level 4. 2024 年 8 月 4 日. WD. URL: https://w3org.cn/TR/css-box-4/
    [CSS-BREAK-4]
    Rossen Atanassov; Elika Etemad. CSS 分片模块 Level 4. 2018 年 12 月 18 日. FPWD. URL: https://w3org.cn/TR/css-break-4/
    [CSS-CASCADE-5]
    Elika Etemad; Miriam Suzanne; Tab Atkins Jr.. CSS Cascading and Inheritance Level 5. 2022年1月13日. CR. URL: https://w3org.cn/TR/css-cascade-5/
    [CSS-DISPLAY-3]
    Elika Etemad; Tab Atkins Jr.. CSS Display Module Level 3. 2023年3月30日. CR. URL: https://w3org.cn/TR/css-display-3/
    [CSS-DISPLAY-4]
    Elika Etemad; Tab Atkins Jr.. CSS 显示模块 Level 4. 2024 年 12 月 19 日. FPWD. URL: https://w3org.cn/TR/css-display-4/
    [CSS-FLEXBOX-1]
    Tab Atkins Jr.; et al. CSS Flexible Box Layout Module Level 1. 2018年11月19日. CR. URL: https://w3org.cn/TR/css-flexbox-1/
    [CSS-GRID-2]
    Tab Atkins Jr.; Elika Etemad; Rossen Atanassov. CSS 网格布局模块 2 级. 2020 年 12 月 18 日. CRD. URL: https://w3org.cn/TR/css-grid-2/
    [CSS-IMAGES-3]
    Tab Atkins Jr.; Elika Etemad; Lea Verou. CSS 图像模块第 3 级. 2023 年 12 月 18 日. CRD. URL: https://w3org.cn/TR/css-images-3/
    [CSS-INLINE-3]
    Elika Etemad. CSS 内联布局模块 Level 3. 2024 年 12 月 18 日. 工作草案 (WD). URL: https://w3org.cn/TR/css-inline-3/
    [CSS-OVERFLOW-3]
    Elika Etemad; Florian Rivoal. CSS Overflow Module Level 3. 2023年3月29日. WD. URL: https://w3org.cn/TR/css-overflow-3/
    [CSS-POSITION-3]
    Elika Etemad; Tab Atkins Jr.. CSS 定位布局模块 Level 3. 2025 年 3 月 11 日. WD. URL: https://w3org.cn/TR/css-position-3/
    [CSS-PSEUDO-4]
    Daniel Glazman; Elika Etemad; Alan Stearns. CSS 伪元素模块 Level 4. 2022年12月30日. WD. URL: https://w3org.cn/TR/css-pseudo-4/
    [CSS-SIZING-3]
    Tab Atkins Jr.; Elika Etemad. CSS Box Sizing Module Level 3. 2021年12月17日. WD. URL: https://w3org.cn/TR/css-sizing-3/
    [CSS-SIZING-4]
    Tab Atkins Jr.; Elika Etemad; Jen Simmons. CSS 盒模型尺寸模块第 4 级. 2021年5月20日. WD. URL: https://w3org.cn/TR/css-sizing-4/
    [CSS-SYNTAX-3]
    Tab Atkins Jr.; Simon Sapin. CSS 语法模块 3 级 (CSS Syntax Module Level 3). 2021年12月24日. CRD. URL: https://w3org.cn/TR/css-syntax-3/
    [CSS-TEXT-4]
    Elika Etemad; 等. CSS 文本模块 Level 4. 2024 年 5 月 29 日. WD. URL: https://w3org.cn/TR/css-text-4/
    [CSS-VALUES-3]
    Tab Atkins Jr.; Elika Etemad. CSS 值与单位模块 3 级 (CSS Values and Units Module Level 3). 2024年3月22日. CRD. URL: https://w3org.cn/TR/css-values-3/
    [CSS-VALUES-4]
    Tab Atkins Jr.; Elika Etemad. CSS 值与单位模块 4 级 (CSS Values and Units Module Level 4). 2024年3月12日. WD. URL: https://w3org.cn/TR/css-values-4/
    [CSS-WRITING-MODES-4]
    Elika Etemad; Koji Ishii. CSS Writing Modes Level 4. 2019年7月30日. CR. URL: https://w3org.cn/TR/css-writing-modes-4/
    [CSS2]
    Bert Bos; et al. 层叠样式表 2 级修订版 1 (CSS 2.1) 规范 (Cascading Style Sheets Level 2 Revision 1 (CSS 2.1) Specification). 2011年6月7日. REC. URL: https://w3org.cn/TR/CSS2/
    [CSS3-BREAK]
    Rossen Atanassov; Elika Etemad. CSS Fragmentation Module Level 3. 2018年12月4日. CR. URL: https://w3org.cn/TR/css-break-3/
    [CSS3-WRITING-MODES]
    Elika Etemad; Koji Ishii. CSS Writing Modes Level 3. 2019年12月10日. REC. URL: https://w3org.cn/TR/css-writing-modes-3/
    [CSSOM]
    Daniel Glazman; Emilio Cobos Álvarez. CSS Object Model (CSSOM). 2021年8月26日. WD. URL: https://w3org.cn/TR/cssom-1/
    [INFRA]
    Anne van Kesteren; Domenic Denicola. Infra 标准. Living Standard. URL: https://infra.spec.whatwg.org/
    [MEDIAQUERIES-5]
    Dean Jackson; 等人. Media Queries Level 5. 2021年12月18日. WD. URL: https://w3org.cn/TR/mediaqueries-5/
    [RFC2119]
    S. Bradner. RFC 中用于指示要求级别的关键词. 1997年3月. Best Current Practice. URL: https://datatracker.ietf.org/doc/html/rfc2119
    [WEB-ANIMATIONS-1]
    Brian Birtles; 等人. Web Animations. 2023年6月5日. WD. URL: https://w3org.cn/TR/web-animations-1/

    参考资料

    [CSS-MULTICOL-2]
    Florian Rivoal; Rachel Andrew. CSS 多列布局模块 Level 2。2024 年 12 月 19 日。FPWD。URL: https://w3org.cn/TR/css-multicol-2/
    [HTML]
    Anne van Kesteren; et al. HTML 标准. Living Standard. URL: https://html.whatwg.cn/multipage/

    属性索引

    名称初始值应用于继承百分比动画类型 (Animation type)规范顺序计算值
    grid <'grid-template'> | <'grid-template-rows'> / [ auto-flow && dense? ] <'grid-auto-columns'>? | [ auto-flow && dense? ] <'grid-auto-rows'>? / <'grid-template-columns'>none(无)网格容器见各个属性见各个属性见各个属性按语法见各个属性
    grid-area <grid-line> [ / <grid-line> ]{0,3}auto网格项和容器块为网格容器的绝对定位框不适用离散 (discrete)按语法见各个属性
    grid-auto-columns <track-size>+auto网格容器见轨道尺寸调整如果列表长度匹配,则按计算值类型进行插值;否则进行离散插值按语法见轨道尺寸调整
    grid-auto-flow [ row | column ] || denserow网格容器不可用离散 (discrete)按语法指定的关键字
    grid-auto-rows <track-size>+auto网格容器见轨道尺寸调整如果列表长度匹配,则按计算值类型进行插值;否则进行离散插值按语法见轨道尺寸调整
    grid-column <grid-line> [ / <grid-line> ]?auto网格项和容器块为网格容器的绝对定位框不适用离散 (discrete)按语法见各个属性
    grid-column-end <grid-line>auto网格项和容器块为网格容器的绝对定位框不可用离散 (discrete)按语法指定的关键字、标识符和/或整数
    grid-column-start <grid-line>auto网格项和容器块为网格容器的绝对定位框不可用离散 (discrete)按语法指定的关键字、标识符和/或整数
    grid-row <grid-line> [ / <grid-line> ]?auto网格项和容器块为网格容器的绝对定位框不适用离散 (discrete)按语法见各个属性
    grid-row-end <grid-line>auto网格项和容器块为网格容器的绝对定位框不可用离散 (discrete)按语法指定的关键字、标识符和/或整数
    grid-row-start <grid-line>auto网格项和容器块为网格容器的绝对定位框不可用离散 (discrete)按语法指定的关键字、标识符和/或整数
    grid-template none | [ <'grid-template-rows'> / <'grid-template-columns'> ] | [ <line-names>? <string> <track-size>? <line-names>? ]+ [ / <explicit-track-list> ]?none(无)网格容器见各个属性见各个属性见各个属性按语法见各个属性
    grid-template-areas none | <string>+none(无)网格容器不可用离散 (discrete)按语法关键字 none 或字符串值列表
    grid-template-columns none | <track-list> | <auto-track-list>none(无)网格容器参考内容区域的相应维度如果列表长度匹配,按计算轨道列表中的每项的计算值类型(见和);否则离散按语法关键字 none 或计算轨道列表
    grid-template-rows none | <track-list> | <auto-track-list>none(无)网格容器参考内容区域的相应维度如果列表长度匹配,按计算轨道列表中的每项的计算值类型(见和);否则离散按语法关键字 none 或计算轨道列表

    问题索引

    如果您注意到此网格布局模块与 弹性盒布局模块 之间存在任何不一致,请向 CSSWG 报告,因为这很可能是一个错误。
    上述列表的第一个要点意味着隐式轨道被序列化为 grid-template-rows/等的组成部分,尽管作者实际上无法在这些属性中指定隐式轨道尺寸!因此 grid-template-rowsgrid-template-columns 的值可能无法正确往返。
    const s = getComputedStyle(gridEl);
    gridEl.style.gridTemplateRows = s.gridTemplateRows;
    // Code like this should be a no-op,
    // but if there are any implicit rows,
    // this will convert them into explicit rows,
    // possibly changing how grid items are positioned
    // and altering the overall size of the grid!
    

    这是早期实现的一个偶然属性,在没有过多考虑的情况下泄露到了后续的实现中。我们打算将其从规范中删除,但要在我们定义好用于获取有关隐式轨道信息的 CSSOM API 之后,因为目前这是获取该信息的唯一方式,且许多页面都依赖于此。

    CSS 工作组正在考虑是否也为 网格放置属性 返回使用值,并正在寻求反馈,特别是来自实现者的反馈。参见 讨论
    是否有助于采用 启发式方法 来尝试更准确的初始估计?例如,假设其 可用空间 为以下项的最大值:
    • 它跨越的所有 确定性 轨道尺寸之和(使用轨道最小和最大尺寸函数中的最大值,如果两者都是确定的,则使用 fit-content() 的参数,如果该参数是确定的)。
    • 该项目的 min-content 尺寸(如果它跨越的任何轨道具有 min-contentfit-content() 尺寸函数)。
    • 该项目的 自动最小尺寸(如果它跨越的任何轨道具有 auto 最小尺寸函数)。
    • 无穷大(如果它跨越的任何轨道具有 max-content 最小尺寸函数,或 max-contentauto<flex> 最大尺寸函数)。

    这或许可以减少所需的重新布局次数,但在任何情况下是否会产生不同或更好的结果?我们是否应该将其采纳到规范中?