Grid 是什么

Flexbox 解决的是"一维"排列——一行或一列;而 Grid(网格布局)是真正的"二维"布局系统,可以同时控制行和列。页面骨架、图片墙、仪表盘这类需要横竖对齐的场景,用 Grid 会比 Flexbox 省事得多。

先记住两个角色:设置 display: grid 的元素叫网格容器,它的直接子元素叫网格项目。

三行代码画出两列布局

.container {
  display: grid;
  grid-template-columns: 200px 1fr;  /* 第一列固定 200px,剩余空间给第二列 */
  gap: 16px;                         /* 行列间距都是 16px */
}

fr 是 Grid 专属单位,表示"剩余空间的份数"。1fr 1fr 就是两列平分,2fr 1fr 就是 2:1 分:

.container {
  display: grid;
  grid-template-columns: 1fr 1fr;  /* 两列均分剩余空间 */
  gap: 16px;
}

行同理,用 grid-template-rows 定义。行列同时定义时,项目会按"先填满一行、再换下一行"的顺序自动排进去。

列数多时用 repeat()

列很多时手写很啰嗦,repeat() 可以批量生成轨道:

.container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);   /* 等价于 1fr 1fr 1fr */
  gap: 16px;
}

配合 auto-fill 还能做出自动换行的响应式卡片墙,一行媒体查询都不用写:

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

含义:每列最窄 200px,屏幕够宽就多放几列,放不下自动换到下一行。

让项目跨行跨列

网格线从 1 开始编号,用 grid-column / grid-row 指定项目占哪几条线之间:

.header {
  grid-column: 1 / 3;   /* 从第 1 条列线到第 3 条列线,横跨两列 */
}

.sidebar {
  grid-row: 2 / 4;      /* 纵向跨两行 */
}

也可以用 span 关键字表达"跨几份":grid-column: span 2; 表示占两列,写起来更直观。

对齐方式

和 Flexbox 类似:容器上用 justify-items(水平)、align-items(垂直)控制项目在自己格子内的对齐;用 justify-content、align-content 控制整个网格在容器中的对齐。

一个实用速记是 place-items: center;,一行代码就能让项目在格子里水平垂直同时居中。

Grid 还是 Flexbox?

简单判断:只有一行或一列要排 → Flexbox;行和列都要对齐(整页布局、卡片墙)→ Grid。两者不冲突,同一个页面里经常配合使用:Grid 搭页面骨架,Flexbox 处理每个模块内部的小排列。

小结

  • display: grid 开启网格布局,grid-template-columns / rows 定义行与列
  • fr 按份分剩余空间,repeat() 批量声明轨道,gap 控制间距
  • repeat(auto-fill, minmax(200px, 1fr)) 是免媒体查询的响应式卡片墙公式
  • grid-column: 1 / 3 让项目跨列,span 2 表示跨两份
  • 一维用 Flexbox,二维用 Grid,二者互补而不是互斥