基于线与区域放置
基于 CSS 现代标准 · 核于 2026-06
速查
- 网格线从
1编号:N 列有 N+1 条竖线;grid-column/grid-row用「起始线 / 结束线」放置 - 列放置:
grid-column: 1 / 3(从第 1 条占到第 3 条 = 跨 2 列);grid-row: 2 / 4同理 - 跨越关键字
span:grid-column: span 2(跨 2 列、起点交给自动布局);grid-column: 2 / span 3(从线 2 起跨 3 列) - 单格可省结束值:
grid-column: 2等价grid-column: 2 / 3 - 负数线从末尾数:
-1是最后一条线;grid-column: 1 / -1= 横跨整个显式网格 - 分量属性:
grid-column-start/grid-column-end/grid-row-start/grid-row-end - 命名线:
grid-template-columns: [sidebar-start] 200px [sidebar-end] 1fr→grid-column: sidebar-start / sidebar-end grid-area: r1 / c1 / r2 / c2一次写四条线(行起 / 列起 / 行止 / 列止)grid-area双重身份:写名字=认领命名区域;写数字=四线简写- 重叠靠
z-index:多个项落到同一格会重叠,用z-index控制层级
网格线坐标系
放置元素的最底层机制,是基于线:每条网格线有编号,从 1 开始(左到右、上到下)。把项「钉」在哪两条线之间,它就占据其间的轨道。
列线: 1 2 3 4
│ │ │ │
├─────┼─────┼─────┤
│ A │ B │ C │ ← 三列 = 四条竖线
└─────┴─────┴─────┘三列的网格有 4 条竖线。grid-column 和 grid-row 用「起始线 / 结束线」两个编号描述项占据的范围:
.item {
grid-column-start: 1; /* 列:从第 1 条竖线 */
grid-column-end: 4; /* 到第 4 条竖线 = 横跨全部 3 列 */
grid-row-start: 1; /* 行:从第 1 条横线 */
grid-row-end: 3; /* 到第 3 条横线 = 纵跨 2 行 */
}简写:grid-column / grid-row 加斜杠
四个分量属性太啰嗦,日常用斜杠简写:起始线 / 结束线。
.item {
grid-column: 1 / 4; /* = grid-column-start:1; grid-column-end:4 */
grid-row: 1 / 3;
}
/* 只占一格时可省略结束值 */
.item {
grid-column: 2; /* 等价 grid-column: 2 / 3 */
}span:我不关心起点,只要跨几格
很多时候你只想说「这个项占 2 列」,至于从哪列开始交给自动布局——这就是 span:
/* 跨 2 列,起点由自动布局决定 */
.wide {
grid-column: span 2;
}
/* 从第 2 条线开始,向后跨 3 列(到第 5 条线) */
.item {
grid-column: 2 / span 3;
}
/* 从某条线「往回」跨:到第 4 条线、向前跨 2 列(即从第 2 条线开始) */
.item {
grid-column: span 2 / 4;
}span N 既能放在起始侧也能放在结束侧,配合另一端的具体线号,能灵活表达「锚定一端、延伸 N 格」。
负数线:从末尾倒数,-1 即最后一条
线编号也能用负数,从网格末尾往回数:-1 是最后一条线、-2 是倒数第二条。最实用的写法是「占满整行」:
/* 无论网格有多少列,都从第一条线占到最后一条线 = 横跨整个显式网格 */
.full-width {
grid-column: 1 / -1;
}grid-column: 1 / -1 是 Grid 里出现频率极高的惯用法——做「整页通栏的标题 / 分隔条」时,不必知道有几列,一行搞定。
负数线只认「显式网格」
-1 指向的是显式网格(你用 grid-template-columns/rows 显式定义的部分)的最后一条线。如果元素被放进了隐式网格(自动新增的轨道,见 隐式网格与自动布局),负数线数不到那些隐式轨道——这是 1 / -1 在自动布局场景下偶尔「不如预期」的根源。
命名线:给坐标起名字
记数字线号容易出错,可以在 grid-template-columns / grid-template-rows 里给线起名(方括号包裹,一条线可起多个名):
.container {
display: grid;
grid-template-columns:
[full-start] 1fr
[main-start] minmax(0, 60ch)
[main-end] 1fr
[full-end];
}
/* 用名字放置,远比记「2 / 3」直观 */
.article {
grid-column: main-start / main-end;
}
.bleed {
grid-column: full-start / full-end;
}一条线可挂多个名字,空格分隔:
grid-template-columns: [sidebar-end main-start] 1fr [main-end];命名线与命名区域互通
上一页 模板区域 提到:定义区域 xxx 会自动生成 xxx-start / xxx-end 命名线。反过来也成立——如果你手动定义了一对 xxx-start / xxx-end 线,就隐式形成了可被 grid-area: xxx 引用的区域。两套体系完全打通,可混用。
grid-area:一个属性的两副面孔
grid-area 容易让人困惑,因为它有两种完全不同的用法:
用法一:认领命名区域(写名字)
配合容器的 grid-template-areas,值是区域名:
.sidebar {
grid-area: sidebar; /* 认领模板里叫 sidebar 的区域 */
}用法二:四条线的简写(写数字 / 线名)
值是四个线坐标,顺序是 行起始 / 列起始 / 行结束 / 列结束:
.item {
/* 行 1→3,列 2→4,即纵跨 2 行、横跨 2 列 */
grid-area: 1 / 2 / 3 / 4;
}记忆顺序:从 row-start 开始,逆时针绕一圈(上 → 左 → 下 → 右)。等价于:
.item {
grid-row: 1 / 3;
grid-column: 2 / 4;
}别把两种用法混在一起
看到 grid-area: header 是「认领区域」,看到 grid-area: 1 / 1 / 3 / 2 是「四线简写」。值里有没有斜杠、是名字还是数字,决定了它走哪条路。两者不能混写。
重叠与层级:z-index
基于线放置允许多个项落到同一个单元格,于是它们会重叠——这正是做「图片上压标题」「徽标盖在卡片角」的原生手段:
.stack {
display: grid;
grid-template-columns: 1fr;
grid-template-rows: 1fr;
}
/* 两个子元素都放进唯一的格子,叠在一起 */
.stack > .photo,
.stack > .caption {
grid-column: 1;
grid-row: 1;
}
.stack > .caption {
z-index: 1; /* 标题压在图片之上 */
align-self: end; /* 贴到格子底部 */
}网格项默认按源顺序决定堆叠,用 z-index 可显式调整。配合 align-self / justify-self 还能把重叠的项对齐到格子的任意角落。
下一步
到这里,你已掌握「在已定义的网格里精确放置」的全部语法。但当项的数量超过显式网格、或你压根没定义行时,Grid 会自动新增轨道——这套「隐式网格 + 自动布局」的规则,以及响应式关键的 auto-fill / auto-fit,是下一页的主题:隐式网格与自动布局。