CSS subgrid 是 CSS Grid Layout Module Level 2 引入的子网格特性(Chrome 117+ 2023 年 9 月、Firefox 71+ 2019 年、Safari 16+ 2022 年全主流浏览器支持),允许嵌套的 grid 容器继承父网格的轨道定义——通过将子网格的 grid-template-columns 或 grid-template-rows 设为 subgrid,子网格直接复用父网格对应方向的轨道,实现嵌套元素的轨道级精确对齐。这一特性让”嵌套网格无法对齐父网格轨道”这一长期痛点从”百分比硬凑或放弃嵌套”升级为”原生轨道继承”,在保持嵌套语义的同时实现对齐。本文系统解析 subgrid 的语法、四种方向、跨列跨行、gap 继承、兼容性与实战案例。
一、诞生背景与核心价值
在 subgrid 出现之前,实现嵌套网格对齐主要有三条路,各有硬伤:
- 独立嵌套 grid:子网格独立定义
grid-template-columns,与父网格轨道无关联。父网格1fr 2fr 1fr,子网格1fr 1fr,列线完全错位。嵌套元素无法对齐父网格列,视觉上参差不齐。 - 百分比硬凑对齐:用百分比让子网格列宽近似父网格列宽。脆弱——父网格轨道变化(如响应式断点切换)即失效,需手动同步两套轨道定义,维护成本高。
- 放弃嵌套用扁平结构:把所有元素放在同一层 grid 中,避免嵌套。语义丢失——无法用嵌套结构表达组件边界,CSS 选择器变复杂,组件复用性下降。
subgrid 提供了原生的轨道继承机制:
/* 父网格定义轨道 */
.parent {
display: grid;
grid-template-columns: 1fr 2fr 1fr;
gap: 16px;
}
/* 子网格继承父网格列轨道 */
.child {
grid-column: span 3; /* 跨父网格 3 列 */
display: grid;
grid-template-columns: subgrid; /* 继承父网格列轨道 */
/* gap 自动继承父网格,无需重复声明 */
}
三大核心价值:一是轨道级精确对齐——子网格列线与父网格列线完全对齐,父网格轨道变化时子网格自动跟随;二是gap 自动继承——subgrid 方向下子网格的 gap 继承父网格,无需手动同步;三是保持嵌套语义——组件边界清晰,CSS 选择器简洁,复用性强。
二、语法与基本用法
subgrid 的核心语法非常简洁——将 grid-template-columns 或 grid-template-rows 的值设为 subgrid 关键字即可:
.child {
display: grid;
/* 继承父网格列轨道 */
grid-template-columns: subgrid;
/* 继承父网格行轨道 */
grid-template-rows: subgrid;
}
关键规则:
- 子网格必须是 grid 容器:
display: grid或display: inline-grid,否则 subgrid 无效。 - 子网格必须是父网格的项:subgrid 只能继承”祖先网格”的轨道,不能跨任意 DOM 层级继承(中间不能有非 grid 容器)。
- 继承的轨道数 = 跨越的父网格轨道数:子网格通过
grid-column: span N决定继承多少条父网格列轨道。例如父网格 4 列,子网格grid-column: span 2且columns: subgrid,则子网格有 2 条列轨道,与父网格对应 2 列完全对齐。 - gap 自动继承:subgrid 方向下,子网格的
gap(row-gap与column-gap)自动继承父网格的 gap 值,无需重复声明。
三、四种方向详解
subgrid 支持四种方向组合,按需选择:
1. none(不继承,对比基线)
.child {
display: grid;
grid-template-columns: 1fr 1fr 1fr; /* 独立定义,不对齐父网格 */
gap: 8px; /* 独立 gap */
}
子网格独立定义轨道,与父网格无关联。这是传统嵌套 grid 的行为,作为对比基线观察 subgrid 的对齐效果。
2. columns(仅列继承)
.child {
grid-column: span 3;
display: grid;
grid-template-columns: subgrid; /* 继承父网格列轨道 */
grid-template-rows: auto; /* 行轨道独立定义 */
}
子网格列对齐父网格列,行轨道独立。最常用方向,覆盖 80% 场景。典型应用:卡片墙(卡片内列对齐父网格列)、表单(标签列与输入框列对齐)、杂志排版(文章列对齐版面列)。
3. rows(仅行继承)
.child {
grid-row: span 3;
display: grid;
grid-template-rows: subgrid; /* 继承父网格行轨道 */
grid-template-columns: 1fr; /* 列轨道独立定义 */
}
子网格行对齐父网格行,列轨道独立。适合需要行对齐的场景,如时间轴、日程表、垂直堆叠的卡片组。
4. both(双向继承)
.child {
grid-column: span 3;
grid-row: span 2;
display: grid;
grid-template-columns: subgrid; /* 继承父网格列轨道 */
grid-template-rows: subgrid; /* 继承父网格行轨道 */
}
子网格列与行都对齐父网格。约束最强,灵活性最低,适合需要完整对齐的场景,如仪表盘卡片(行列都需要对齐)、复杂嵌套表格布局。
选型建议:优先用 columns(覆盖 80% 场景),只有确实需要行对齐时才升级为 both。subgrid 方向越多,约束越强,灵活性越低。
四、跨列跨行与继承轨道数
子网格通过 grid-column: span N 与 grid-row: span N 在父网格中定位,决定它继承多少条父网格轨道:
.parent {
display: grid;
grid-template-columns: repeat(4, 1fr); /* 父网格 4 列 */
grid-template-rows: repeat(2, 100px); /* 父网格 2 行 */
gap: 16px;
}
.child {
grid-column: span 2; /* 跨父网格 2 列 */
grid-row: span 2; /* 跨父网格 2 行 */
display: grid;
grid-template-columns: subgrid; /* 继承 2 条父网格列轨道 */
grid-template-rows: subgrid; /* 继承 2 条父网格行轨道 */
}
关键规则:子网格继承的轨道数 = 跨越的父网格轨道数。上例中子网格跨 2 列 2 行,因此继承 2 条列轨道 + 2 条行轨道,子网格内部是 2×2 的网格,与父网格对应区域完全对齐。
实践建议:跨列数应与子网格内项的预期列数匹配。例如子网格跨 3 列且希望 6 个项排成 2 行 3 列,则 grid-column: span 3 + grid-template-columns: subgrid 即可,6 个项自动按 3 列排列,且每列对齐父网格列。
五、gap 继承机制
subgrid 方向下,子网格的 gap(row-gap 与 column-gap)自动继承父网格的 gap 值,无需重复声明:
.parent {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
gap: 16px; /* 父网格 gap */
}
.child {
grid-column: span 3;
display: grid;
grid-template-columns: subgrid;
/* 无需声明 gap,自动继承父网格的 16px */
}
部分继承:只有 subgrid 方向的 gap 会继承。若子网格只 columns: subgrid 而 rows 独立定义,则 column-gap 继承父网格,row-gap 可独立设置:
.child {
grid-column: span 3;
display: grid;
grid-template-columns: subgrid; /* 列轨道继承 */
grid-template-rows: auto; /* 行轨道独立 */
row-gap: 8px; /* 行间距独立设置 */
/* column-gap 自动继承父网格 */
}
这是 subgrid 的核心便利之一——父子网格间距保持一致,无需手动同步,避免了”父网格 gap 变了但子网格忘记改”的常见 bug。
六、浏览器兼容性与渐进降级
兼容性现状
subgrid 已全主流浏览器支持:
| 浏览器 | 支持版本 | 发布时间 |
|---|---|---|
| Chrome | 117+ | 2023 年 9 月 |
| Firefox | 71+ | 2019 年 |
| Safari | 16+ | 2022 年 |
| Edge | 117+ | 2023 年 9 月(跟随 Chromium) |
截至 2024 年底全球浏览器支持率已超 95%,可放心用于生产环境。
渐进降级策略
不支持的浏览器会忽略 subgrid 值,子网格退化为独立网格(无轨道继承)。推荐写法:
.child {
display: grid;
/* 降级:独立定义轨道 */
grid-template-columns: 1fr 1fr 1fr;
gap: 16px;
/* 增强:subgrid 继承 */
grid-template-columns: subgrid;
/* subgrid 方向下 gap 自动继承,降级时使用上面的 16px */
}
先写降级值,再用 subgrid 覆盖。支持的浏览器用 subgrid 对齐,不支持的用独立网格,两者都能正常渲染,只是对齐精度不同。这是天然的渐进增强——零额外开销,新旧浏览器体验都不差。
特性检测:
@supports (grid-template-columns: subgrid) {
.child {
grid-template-columns: subgrid;
}
}
用 @supports 检测 subgrid 支持,仅支持的浏览器启用。但上述”先降级后增强”写法已足够,无需额外特性检测。
七、实战案例与最佳实践
案例 1:卡片墙列对齐
卡片墙中每张卡片内部的列与父网格列对齐——卡片头部、内容、底部分别对齐父网格列:
.card-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 20px;
}
.card {
display: grid;
grid-template-rows: subgrid; /* 继承父网格行轨道 */
grid-row: span 3; /* 跨 3 行:头部/内容/底部 */
/* 卡片内 3 行自动对齐父网格行 */
}
案例 2:表单标签输入对齐
表单中标签列与输入框列跨字段对齐:
.form {
display: grid;
grid-template-columns: 100px 1fr;
gap: 12px;
}
.field {
display: grid;
grid-template-columns: subgrid; /* 继承父网格 2 列 */
grid-column: span 2;
/* 标签与输入框自动对齐父网格的 100px 和 1fr 列 */
}
案例 3:杂志嵌套排版
杂志式排版,主内容区子网格继承父网格列轨道:
.magazine {
display: grid;
grid-template-columns: 160px 2fr 1fr;
gap: 16px;
}
.article {
grid-column: span 2; /* 跨主内容区 2 列 */
display: grid;
grid-template-columns: subgrid;
/* 文章内容列对齐版面列 */
}
最佳实践
- 优先用 columns 方向:覆盖 80% 场景,约束适中,灵活性高。
- 跨列数与预期列数匹配:子网格跨 N 列 +
columns: subgrid,内部项自动按 N 列排列。 - gap 无需重复声明:subgrid 方向下 gap 自动继承,重复声明会被覆盖。
- 先降级后增强:先写独立轨道定义,再用 subgrid 覆盖,实现渐进增强。
- 避免过度使用:subgrid 约束强,不是所有嵌套都需要对齐。只在确实需要轨道级对齐时使用。
八、配套工具协同与总结
subgrid 与本站其他 CSS 布局工具形成协同:
- CSS Grid 可视化生成器(/grid):定义父网格轨道,与 subgrid 配合实现嵌套对齐。先用 Grid 工具设计父网格,再用 subgrid 工具让子网格继承。
- CSS Flexbox 可视化生成器(/flexbox):一维布局,组件内排列。Grid + subgrid 处理二维嵌套对齐,Flexbox 处理组件内一维排列。
- CSS @container 容器查询(/container):组件级响应式。subgrid 解决嵌套对齐,@container 解决组件级响应式,两者互补。
- CSS Nesting 原生嵌套(/nesting):选择器嵌套语法。subgrid 是网格嵌套,Nesting 是选择器嵌套,不同维度的嵌套能力。
总结:subgrid 是 CSS Grid 布局能力的重要补全——从”独立嵌套网格”升级为”轨道继承网格”,让嵌套结构保持语义的同时实现轨道级精确对齐。掌握四种方向选型、跨列跨行与继承轨道数关系、gap 继承机制,即可在卡片墙、表单、杂志排版等场景中游刃有余。配合渐进降级策略,可放心用于生产环境。立即使用 CSS subgrid 子网格生成器 可视化生成嵌套网格轨道继承效果。