跳到主要内容

Grid 轨道尺寸与间距

定义行与列

固定尺寸与百分比

.container {
display: grid;
grid-template-columns: 240px 1fr;
grid-template-rows: 64px auto 80px;
}

⚠️ 百分比轨道 + gap 很容易溢出:50% + 50% + 20px > 100%。弹性布局请用 fr,它会自动扣除 gap 后再分配。

fr 到底怎么算

fr 表示「分配完固定尺寸、内容最小尺寸和间距后,剩余空间所占的份数」。

假设容器宽 800px

.container {
display: grid;
grid-template-columns: 200px 1fr 2fr;
gap: 20px;
}

计算过程:

  1. 先扣掉固定轨道:800 - 200 = 600
  2. 再扣掉间距(3 列有 2 道缝):600 - 40 = 560
  3. 剩余 560px1 : 2 分:1fr ≈ 186.7px2fr ≈ 373.3px

最终三列约为 200px / 186.7px / 373.3px

1frminmax(0, 1fr)(最常见的溢出根源)

1fr 实际等价于 minmax(auto, 1fr),而这个 auto 最小值会尊重内容的最小尺寸。长 URL、代码块、不换行的表格都可能把轨道撑破。

/* ❌ 一个超长 URL 就能把这一列撑爆,连带挤得侧边栏变形 */
.bad { grid-template-columns: 240px 1fr; }

/* ✅ 允许该列收缩到 0,再在内部处理溢出 */
.good { grid-template-columns: 240px minmax(0, 1fr); }

💡 经验法则:只要某一列可能装下不可预测的用户内容(正文、代码、聊天消息),就写 minmax(0, 1fr) 而不是 1fr****。

repeat()

.container {
grid-template-columns: repeat(4, 1fr);
}

等价于 grid-template-columns: 1fr 1fr 1fr 1fr;

也可以重复一组轨道,常用于「标签 + 值」交替的信息展示:

/* 标签列自适应、值列弹性,重复 3 组 */
grid-template-columns: repeat(3, max-content 1fr);

minmax()

.container {
grid-template-columns: repeat(3, minmax(180px, 1fr));
}

每列至少 180px,空间充足时平均扩展。

auto-fillauto-fit:用具体数字看差别

.card-list {
display: grid;
/* 分别把 AUTO 换成 auto-fill / auto-fit 对比 */
grid-template-columns: repeat(AUTO, minmax(200px, 1fr));
gap: 20px;
}

容器宽 1000px,最多可放 4 列(4 × 200 + 3 × 20 = 860 ≤ 1000)。此时只有 2 个卡片

关键字生成的轨道卡片实际宽度视觉效果
auto-fill4 条轨道,后 2 条为空但保留各约 235px卡片靠左排,右侧空出两个位置
auto-fit4 条轨道,空轨道被折叠为 0各约 490px两个卡片拉伸铺满整行

选择建议:

  • 希望卡片宽度稳定、不因数量变化而突变auto-fill
  • 希望内容始终铺满一行、不留空白auto-fit
  • 当元素足够填满一行时,两者看起来完全一样;元素少时差异才明显。

防止窄屏横向溢出:

/* ❌ 容器宽 180px 时,200px 的最小值会横向溢出 */
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));

/* ✅ 容器比 200px 还窄时,自动退化为容器宽度 */
grid-template-columns: repeat(auto-fit, minmax(min(100%, 200px), 1fr));

轨道尺寸关键字对照

以一列内容为「Hello World」为例:

关键字行为适合场景
auto受内容和可用空间共同影响,有剩余空间时可能被拉伸通用默认值
min-content收缩到最长单词的宽度(World),文字会换行强制紧凑的标签列
max-content扩展到不换行所需宽度(Hello World),可能溢出按钮组、不希望换行的操作列
fit-content(320px)在内容宽度与 320px 之间取小者宽度随内容变化但需要上限的列
minmax(200px, 1fr)至少 200px,有空间就扩展响应式卡片
minmax(0, 1fr)可收缩到 0,弹性填满主内容区

典型组合——「标签列贴合内容,内容列吃掉剩余空间」,非常适合表单:

.form {
display: grid;
grid-template-columns: max-content minmax(0, 1fr);
gap: 12px 16px;
align-items: center;
}

轨道间距

.container {
row-gap: 12px;
column-gap: 24px;
gap: 12px 24px; /* 行间距 列间距 */
gap: 16px; /* 行列间距相同 */
}
  • gaprow-gapcolumn-gap 的简写。
  • 旧代码中的 grid-gapgrid-row-gapgrid-column-gap 已标准化为不带 grid- 前缀的写法。

gap 只出现在轨道之间,不会加在容器外围。宽度公式:容器宽 = 各列宽之和 + (列数 - 1) × gap

定义轨道时的常见错误

/* ❌ 百分比 + gap 必然溢出 */
grid-template-columns: 50% 50%;
gap: 20px;

/* ✅ fr 会自动扣除 gap */
grid-template-columns: 1fr 1fr;
gap: 20px;

/* ❌ auto-fit 搭配不确定的 auto,浏览器无法推算轨道数 */
grid-template-columns: repeat(auto-fit, auto);

/* ✅ auto-fit / auto-fill 必须搭配确定的最小值 */
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));