CSS Grid 网格布局

CSS Grid 是二维布局的终极方案——它能同时对行和列进行精确控制。如果说 Flexbox 是”一维流水线”,Grid 就是”二维棋盘”。

启用 Grid

css
.container {
  display: grid;
}

容器成为网格容器,直接子元素成为网格项

定义网格结构

grid-template-columns / grid-template-rows

定义网格有多少列、多少行,以及它们的尺寸:

css
.grid {
  display: grid;
  grid-template-columns: 200px 1fr 200px;
  /* 三列:左 200px、中间弹性、右 200px */

  grid-template-rows: auto 1fr auto;
  /* 三行:上下按内容、中间弹性 */
}

fr 单位

fr(fraction,份数)是 Grid 特有的单位,表示剩余空间的比例

css
/* 等分三列 */
.grid {
  grid-template-columns: 1fr 1fr 1fr;
}

/* 中间列是两侧的两倍宽 */
.grid {
  grid-template-columns: 1fr 2fr 1fr;
}

repeat() 函数

简化重复的列定义:

css
/* 12 列等宽网格 */
.grid-12 {
  grid-template-columns: repeat(12, 1fr);
}

/* 两列模式交替 */
.grid-pattern {
  grid-template-columns: repeat(3, 1fr 2fr);
  /* 1fr 2fr 1fr 2fr 1fr 2fr */
}

间距:gap

与 Flexbox 一样,gap 控制网格项之间的间距:

css
.grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.5rem;       /* 行列间距相同 */
  gap: 1rem 2rem;    /* 行间距 列间距 */
}

网格项放置

默认情况下,网格项按顺序从左到右、从上到下自动放置。你也可以手动指定位置:

css
/* 让 header 跨越整行 */
.header {
  grid-column: 1 / -1; /* 从第一根线到最后根线 */
}

/* 让 sidebar 放在第一列 */
.sidebar {
  grid-column: 1 / 2;
  grid-row: 2 / 3;
}

/* 精确定位 */
.item {
  grid-column-start: 2;
  grid-column-end: 4;
  grid-row-start: 1;
  grid-row-end: 3;
}

1 / -1 是常用写法:-1 代表最后一条网格线,1 / -1 就是”从第一条到最后一条”即占满整行/整列。

grid-area 简写

css
.item {
  grid-area: row-start / col-start / row-end / col-end;
  /* 等价: */
  grid-area: 1 / 2 / 3 / 4;
}

命名的区域模板

grid-template-areas 让你用可视化方式描述布局:

css
.layout {
  display: grid;
  grid-template-columns: 200px 1fr 200px;
  grid-template-rows: auto 1fr auto;
  grid-template-areas:
    "header  header  header"
    "sidebar content aside"
    "footer  footer  footer";
  gap: 1rem;
  min-height: 100vh;
}

.header  { grid-area: header; }
.sidebar { grid-area: sidebar; }
.content { grid-area: content; }
.aside   { grid-area: aside; }
.footer  { grid-area: footer; }
html
<div class="layout">
  <header class="header">页头</header>
  <nav class="sidebar">侧栏</nav>
  <main class="content">内容</main>
  <aside class="aside">附加</aside>
  <footer class="footer">页脚</footer>
</div>

grid-template-areas 是最直观的布局方式——你可以在 CSS 中用文字”画”出页面布局。适合固定结构的页面(如后台管理面板、文档站)。

响应式自动网格

auto-fitauto-fill

无需媒体查询即可创建响应式网格:

css
/* 自适应卡片网格:每列最小 250px,空间充裕时自动增加列数 */
.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 1.5rem;
}
  • auto-fit:拉伸现有项以填满空间
  • auto-fill:留出空白列,不拉伸现有项

这是 Grid 最强大的特性之一——repeat(auto-fit, minmax(250px, 1fr)) 可以在不使用任何媒体查询的情况下实现完美的响应式网格。它相当于告诉浏览器:“每列至少 250px,空间够就多放几列,不够就自动换行”。

对齐方式

属性作用写在
justify-items单元格内的水平对齐容器
align-items单元格内的垂直对齐容器
justify-content网格整体水平对齐容器
align-content网格整体垂直对齐容器
justify-self单个项的水平对齐子项
align-self单个项的垂直对齐子项
css
.grid {
  display: grid;
  justify-items: center;  /* 所有项在单元格内水平居中 */
  align-items: center;    /* 所有项在单元格内垂直居中 */
  /* 简写 */
  place-items: center;
}

.special {
  justify-self: start;    /* 单独这个项左对齐 */
  align-self: end;        /* 单独这个项底对齐 */
}

隐式网格

当你定义的格子不够用时,Grid 会自动创建隐式行(implicit rows):

css
.grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-auto-rows: 150px; /* 隐式行的高度 */
}

Grid vs Flexbox

特性FlexboxGrid
布局维度一维(行 or 列)二维(行 and 列)
内容优先/布局优先内容驱动布局驱动
适合场景导航栏、工具栏、行内元素排列页面骨架、卡片网格、表单布局
典型语法flex-direction, justify-contentgrid-template-columns, grid-template-areas

Grid 和 Flexbox 不是互斥的——它们可以协同工作。一个常见模式是:页面整体用 Grid 划分区域,每个区域内部用 Flexbox 排列子元素。选择哪个取决于”这个容器内需要几维的控制”。