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;
}
计算过程:
- 先扣掉固定轨道:
800 - 200 = 600 - 再扣掉间距(3 列有 2 道缝):
600 - 40 = 560 - 剩余
560px按1 : 2分:1fr ≈ 186.7px,2fr ≈ 373.3px
最终三列约为 200px / 186.7px / 373.3px。
1fr ≠ minmax(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-fill 与 auto-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-fill | 4 条轨道,后 2 条为空但保留 | 各约 235px | 卡片靠左排,右侧空出两个位置 |
auto-fit | 4 条轨道,空轨道被折叠为 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; /* 行列间距相同 */
}
gap是row-gap和column-gap的简写。- 旧代码中的
grid-gap、grid-row-gap、grid-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));