gap作用于网格线之间而非子元素,是网格轨道间的空白槽;需至少两个轨道才生效,单轨道或跨满行列时不可见;单值gap设行列同距,双值先设行距后列距。

gap 只在网格轨道之间生效,不是“给子元素加空隙”,而是“在行线与列线之间画槽”
gap 的作用位置:它不作用于子元素,而作用于网格线之间
很多人误以为 gap 是给每个子项“外边距”,其实它完全不碰子元素的盒模型。它是 CSS Grid 布局引擎在生成**显式网格轨道(grid tracks)** 时,自动插入到相邻行轨道、相邻列轨道之间的“空白槽”(gutter)。这个槽属于容器内部布局结构的一部分,和 margin、padding 完全无关。
- 有 3 列定义:
grid-template-columns: 1fr 1fr 1fr→ 会产生 2 个列间隙(第1–2列之间、第2–3列之间) - 有 4 行内容(即使没写
grid-template-rows)→ 若靠隐式行生成,row-gap仍会作用于每对相邻隐式行之间 - 容器边缘(最左/最右、最上/最下)永远没有 gap —— 这是它比
margin更干净的根本原因
为什么有时 gap 看起来“没生效”?关键看是否真有多个轨道
gap 不是“只要写了就出空隙”,它需要至少两个可分隔的轨道才能体现。常见失效场景:
- 只定义了单列:
grid-template-columns: 1fr,且所有子项都在同一列 → 没有列间隙可产生,column-gap不可见 - 子项用
grid-column: 1 / -1跨满整行 → 它独占一行,上下无其他行项,row-gap无处落脚 - 父容器是
display: grid,但子项被包在一层里 → 真正的 grid item 是 wrapper,不是卡片本身;gap 只作用于 wrapper 之间,而非卡片之间
- 子项用了
display: contents→ 该元素脱离渲染树,不再占据独立网格单元格,gap 就“跨过它”继续计算,视觉上可能断开gap 值怎么解析?单值 vs 双值的语义差异
gap是row-gap和column-gap的简写,但它的值顺序和直觉相反:第一个值是row-gap(垂直方向),第二个才是column-gap(水平方向)。立即学习“前端免费学习笔记(深入)”;
.container { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px 24px; /* ← 行间距 12px,列间距 24px */ }- 写成
gap: 16px→ 等效于row-gap: 16px; column-gap: 16px - 写成
gap: 8px 16px→row-gap: 8px(上下空隙小),column-gap: 16px(左右空隙大) - 不要混用:
gap: 12px和grid-gap: 12px同时存在时,后者会被忽略(现代浏览器中grid-gap已废弃)
gap 和 margin 共存时会发生什么?
它们完全独立,不会合并、抵消或级联——gap 是网格布局层的槽,margin 是子元素自身的外边距。两者叠加就是真实物理距离。
- 如果卡片自身有
margin: 4px,又设了gap: 12px→ 卡片之间实际空隙 = 4px(右 margin) + 12px(gap 槽) + 4px(下一卡片左 margin) = 20px -
解决方法很简单:
.container > * { margin: 0; },把间距控制权彻底交给gap - 若需某张卡片额外偏移,改用
justify-self或place-self,而非加 margin
最容易被忽略的一点:gap 生效的前提不是“有子元素”,而是“有可分隔的网格轨道”。哪怕子元素只有 1 个,只要它被显式或隐式地放在多行/多列结构中(比如设置了
grid-row: 1 / 3),gap 就可能在它上下或左右起效——这取决于轨道划分,而不是元素数量。 - 子项用了

