CSS Handbook · 现代进阶特性

第十一章 / 11.3 Subgrid

第十一章 · 11.3 节

Subgrid


6.4 节讲过,Grid 容器的子元素默认只是"占据"若干个网格单元,子元素内部再想用 Grid 布局,就是一套全新的、跟父网格无关的轨道系统。subgrid 让子网格可以直接"继承"父网格的行/列轨道,从而实现跨嵌套层级的对齐。

没有 subgrid 时的痛点

最常见的场景:一排卡片,每张卡片内部都有标题、正文、底部按钮,希望所有卡片的标题顶部对齐、按钮底部对齐——但每张卡片内容长度不同。如果每张卡片各自建立一套 Grid,它们的行高只能各自撑开,无法跨卡片对齐。

subgrid 语法

把子元素的 grid-template-columns(或 rows)设为 subgrid,它就不再定义自己的轨道尺寸,而是直接复用父网格对应范围内的轨道:

.gallery {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: auto auto auto;
}

.card {
  grid-row: span 3;         /* 占据 3 行 */
  display: grid;
  grid-template-rows: subgrid; /* 复用父网格的 3 行轨道,而不是自己重新计算 */
}
关键区别subgrid 不产生新的轨道尺寸定义,行/列的大小完全由最外层的父网格决定;子元素只是声明"我要对齐到父网格的这几条线"。

卡片列表对齐示例

DEMO · 三张卡片,标题/正文/按钮通过 subgrid 跨卡片对齐(不支持 subgrid 的浏览器会退化为普通网格)
标题

一行正文

标题较长换行

这里正文内容明显更长一些,占据更多行,用来测试跨卡片对齐效果如何

标题

中等长度的正文内容

使用要点

要点说明
继承范围子元素必须先用 grid-column/grid-row 占据父网格中的若干条轨道,subgrid 才能对齐到这个范围内
gap 是否继承subgrid 默认继承父网格的 gap,也可以在子元素上覆盖自己的 gap
浏览器支持主流浏览器已支持,但项目若需兼容旧版本,应准备"退化为普通网格"的降级方案,并用 @supports (grid-template-columns: subgrid) 做特性检测

Chapter 11 · Section 11.3

Subgrid


Section 6.4 explained that a grid container's children merely "occupy" a few grid cells by default; if you want to use Grid inside a child, that is a brand-new track system unrelated to the parent grid. subgrid lets a nested grid directly "inherit" the parent grid's row/column tracks, enabling alignment across nesting levels.

The Pain Points Without subgrid

The most common scenario: a row of cards, each with a title, body text and a bottom button, where you want all titles aligned at the top and all buttons aligned at the bottom — but each card's content has a different length. If every card builds its own grid, the row heights can only be sized independently, so the cards can never align across the row.

subgrid Syntax

Set a child's grid-template-columns (or rows) to subgrid, and instead of defining its own track sizes, it directly reuses the tracks of the parent grid within the corresponding range:

.gallery {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: auto auto auto;
}

.card {
  grid-row: span 3;         /* spans 3 rows */
  display: grid;
  grid-template-rows: subgrid; /* reuses the parent grid's 3 row tracks instead of recomputing its own */
}
Key differencesubgrid creates no new track size definitions — the row/column sizes are entirely determined by the outermost parent grid; the child merely declares "I want to align to these lines of the parent grid".

Example: Aligning a Card List

DEMO · three cards whose titles/body/buttons align across cards via subgrid (browsers without subgrid support fall back to a plain grid)
Title

A line of body text

A longer title that wraps

This body text is noticeably longer and takes up more lines, to test how well the cross-card alignment holds

Title

Body text of medium length

Key Points

PointExplanation
Inherited scopeThe child must first occupy several tracks of the parent grid with grid-column/grid-row, and only then can subgrid align to that range
Does gap inherit?subgrid inherits the parent grid's gap by default, and you can also override gap on the child element
Browser supportMainstream browsers support it, but if the project must support older versions, prepare a "degrade to a plain grid" fallback and feature-detect with @supports (grid-template-columns: subgrid)