CSS Handbook · 布局

第六章 / 6.4 Grid 详解

第六章 · 6.4 节

Grid 详解


如果说 Flexbox 是"一维"的排布工具,那 Grid 就是真正意义上的"二维"布局系统——它能同时控制行与列,让我们第一次可以用纯 CSS 精确描述报刊式的复杂版面,而不必依赖嵌套的 div 拼凑。

与 Flexbox 的分工

FlexboxGrid
维度一维(一行或一列)二维(行与列同时)
驱动方式内容驱动,尺寸由内容撑开布局驱动,先定义轨道再放内容
典型场景导航栏、按钮组、卡片内部排布页面整体骨架、图片墙、杂志排版

实战中二者并非互斥:常见做法是用 Grid 搭建页面级的整体骨架,再用 Flexbox 处理骨架内部每个区块的一维排列。

定义行与列

.layout {
  display: grid;
  grid-template-columns: 220px 1fr;
  grid-template-rows: 64px 1fr 48px;
  gap: 16px;
}

grid-template-columns / grid-template-rows 用空格分隔的一串长度值定义"轨道"(track),每个值对应一条列或一行的尺寸。轨道之间天然形成"网格线"(grid line),从 1 开始编号,也可以用 repeat() 简化重复轨道:

.gallery {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 12px;
}
效果预览:4 列等宽网格
1
2
3
4

fr 单位

fr(fraction)是 Grid 专属的弹性单位,代表"分配剩余空间的份数",与 flex-grow 的思路相通,但更灵活——可以与固定长度混用:

.layout {
  grid-template-columns: 200px 1fr 2fr;
  /* 第一列固定 200px,剩余空间按 1:2 分给第二、三列 */
}

子项定位

子项可以用网格线编号,精确指定自己横跨的起止位置:

.hero {
  grid-column: 1 / 3;   /* 从第 1 条线到第 3 条线,横跨 2 列 */
  grid-row: 1 / 2;
}
/* span 关键字:横跨 N 条轨道,无需关心起止编号 */
.wide { grid-column: span 2; }
效果预览:第二项横跨两列
1
span 2
3
4

grid-template-areas:具名区域

把网格划分成语义化的命名区域,是 Grid 中最具可读性的用法——布局结构在 CSS 里"画"出来,一目了然:

.page {
  display: grid;
  grid-template-columns: 220px 1fr;
  grid-template-areas:
    "sidebar header"
    "sidebar main"
    "sidebar footer";
}
.sidebar { grid-area: sidebar; }
header   { grid-area: header; }
main     { grid-area: main; }
footer   { grid-area: footer; }
提示每一行字符串的单词个数必须与列数一致;用连续的点号 . 可以留出空白区域,不分配给任何子项。

auto-fit / auto-fill / minmax:自适应网格

这是 Grid 中最强大的组合技,能实现"不写媒体查询也能响应式"的卡片网格——根据容器宽度自动决定放几列。

.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 16px;
}

minmax(200px, 1fr) 表示每列最小 200px、最大均分剩余空间;auto-fit 会自动计算能放下几列,并让已有列拉伸填满整行;auto-fill 则会保留"看不见"的空轨道位置,列不会被拉伸得过宽。二者的区别只有在剩余空间不足以再放一列时才会体现出来。

空间足够放下更多列时
auto-fit已有列拉伸,填满整行,不留空轨道
auto-fill保留潜在空轨道的位置,已有列不额外拉伸

隐式网格

当子项数量超出 grid-template-* 定义的轨道数时,浏览器会自动生成"隐式轨道"来容纳多出的内容。用 grid-auto-rows / grid-auto-columns 控制这些隐式轨道的尺寸,grid-auto-flow: dense 则会让排布算法主动回填此前跳过的空隙。

.masonry-like {
  grid-auto-rows: 10px;
  grid-auto-flow: dense;
}

对齐属性总览

Grid 的对齐属性与 Flexbox 一脉相承,但多了"针对整个网格"与"针对单个子项"两个维度:

属性作用对象方向
justify-items所有子项行内方向(水平)
align-items所有子项块方向(垂直)
justify-self单个子项,覆盖 justify-items行内方向
align-self单个子项,覆盖 align-items块方向
justify-content整个网格(当轨道总宽小于容器时)行内方向
align-content整个网格块方向

实战:杂志式排版

结合具名区域、span 与 auto-fit,可以快速搭出一个左侧特写、右侧信息流的版面:

.magazine {
  display: grid;
  grid-template-columns: 2fr 1fr;
  grid-template-rows: repeat(3, auto);
  gap: 16px;
}
.feature { grid-row: span 3; } /* 左侧特写纵跨三行 */
效果预览
特写
条目 1
条目 2
条目 3