进阶四件套:span、minmax() + auto-fit、subgrid、12 栏显式放置

① 跨行跨列:线(line)而不是格子

普通格
grid-column: span 2
A
grid-row: span 2
B
C
D
E
grid-column: 1 / -1 横跨整行(-1 = 最后一条线)
写法含义
grid-column: 2 / 4从第 2 条竖线到第 4 条 → 占第 2、3 两列
grid-column: span 3由自动放置决定起点,跨 3 列
grid-area: 1 / 2 / 4 / 5行开始/列开始/行结束/列结束(顺序同 margin)
1 / -1首尾通吃,写「整行标题 / 整行页脚」最常用

跨度数的轨道如果没被显式定义,会用隐式轨道(尺寸由 grid-auto-rows 决定,默认 auto)。

② 一行代码的响应式:minmax + auto-fit/auto-fill

拖动 iframe 宽度,下面两块会经历同样的断点,但行为不同:auto-fit 会把空轨道压成 0 让现存项铺满,auto-fill 保留空轨道。

auto-fit
A
B
auto-fill
A
B
/* 最小 240px,能放几列放几列,剩余空间按 1fr 平分 */
.cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 16px; }
/* 窄屏只有一个元素时它仍只有 240px 起,min() 让上限不超过容器: */
.cards { grid-template-columns: repeat(auto-fit, minmax(min(240px, 100%), 1fr)); }

③ 实战:卡片墙(无媒体查询的响应式)

特征一Grid 自动决定列数,卡片始终等高。
特征二不需要 @media,靠内容自身宽度决定断点,比按设备宽度更稳。
特征三需要精确控制列数(比如「正好 3 列,窄屏 1 列」)时才回退到媒体查询,见第十三章。
特征四最后一行不满会保持左对齐并占各自轨道 —— 与 Flex 的行为差异,注意别混用。

④ 12 栏栅格:显式放置最直观

span 8
span 4
span 6
span 6
grid-column: 3 / span 6(从第 3 列开始)

⑤ subgrid:让子卡片的内部行列对齐外层网格

短标题

正文较短

按钮底部对齐

较长的标题会占两行

正文长一些,但因为三个面板共享外层网格的轨道,标题行、正文行、按钮行都严格对齐。

按钮

标题

没有 subgrid 时,要在每个面板里硬写行高才能对齐。

按钮
.panel {
  display: grid;
  grid-row: span 3;              /* 先声明跨几行 */
  grid-template-rows: subgrid;   /* 复用父网格的轨道尺寸 */
}
.item { grid-row: subgrid; }     /* 允许子项再往下一层嵌套对齐 */

浏览器基线:subgrid 需要较新的浏览器(Safari 16 / Chrome 117 / Firefox 71 一线),旧内核会退化成普通 Grid 布局而不破坏内容;上线前请以 caniuse 当前数据为准,并用 @supports (grid-template-rows: subgrid) 做渐进增强(第二十章)。

⑥ 常见坑速查

现象原因与修法
设了 1fr 仍横向溢出1fr 的下限是 auto(= min-content)。写 minmax(0, 1fr) 或 min-width: 0
百分比高度不生效用 grid-template-rows 或 align-items: stretch,不要写 height: 100% 猜父高
gap 生效但四边空白不对称四周空白来自容器 padding,不是 gap
auto-fit 时卡片被拉很宽给 1fr 上限:minmax(240px, 320px),外层再 justify-content: center