Skip to content

grid 布局

导航目录

概述

网格布局(CSS Grid)是强大的二维布局方案:同时控制行(row)与列(column)。它把容器划分为网格轨道(tracks),再把子元素放入指定的网格区域,从而实现复杂布局(栅格系统、卡片列表、自适应换行、区域拼接等)。

  • 二维布局:Flex 更擅长“一维”(一行或一列)的排列;Grid 更擅长“二维”(行+列)的整体排布。
  • 核心思路:先定义网格(行/列轨道)→ 再放置网格项(按线、按区域、自动布局)。

基础概念:行(rows)与列(columns)

Grid 网格由行与列共同组成:

  • 行(rows):通常由 grid-template-rows 定义,控制每一行的高度。
  • 列(columns):通常由 grid-template-columns 定义,控制每一列的宽度。

补充两个常见概念:

  • 网格线(grid lines):行/列的分界线,编号从 1 开始;元素可以通过线编号进行放置。
  • 网格单元(cell)/网格区域(area):单元是最小格子;区域可以由多个单元合并组成。

定义网格:fr 单位与等分布局

fr 是 Grid 的“剩余空间分配单位”(fraction)。当列/行使用 fr 时,会在扣除固定宽度与间隙后,将剩余空间按比例分配。

  • 常见写法grid-template-columns: 1fr 1fr 1fr;(三列等分)
  • 混合写法200px 1fr 2fr(先固定,再按比例分配剩余空间)

合并区域:grid-template-areas 与区域命名

当布局更像“页面区域拼图”(header / sidebar / content / footer)时,推荐使用 grid-template-areas

  • 可读性强:用字符串直观看到布局结构
  • 适合大块区域:尤其是典型页面框架布局

注意:区域命名需要配合子元素的 grid-area 使用。

网格间隙及简写

网格轨道之间的间距用 gap 控制(以前常见写法是 grid-gap,现在统一推荐 gap)。

  • 统一间隙gap: 16px;
  • 分别设置行/列间隙row-gap: 12px; column-gap: 20px;
  • 简写(行 列)gap: 12px 20px;

网格对齐方式及简写

Grid 的对齐分两类,容易混淆:

  • 容器层(整张网格在容器里的对齐)justify-content(水平)/ align-content(垂直)
  • 单元层(网格项在单元格里的对齐)justify-items(水平)/ align-items(垂直)

同时提供简写:

  • place-content: <align-content> <justify-content>;
  • place-items: <align-items> <justify-items>;
  • 单个元素还可用 justify-self / align-self 覆盖自身对齐。

显式网格与隐式网格

基于线的元素放置

显式网格(Explicit Grid)是你通过 grid-template-rows / grid-template-columns 明确声明的轨道数量。 当网格项数量或放置位置超出显式网格范围时,浏览器会自动创建隐式网格(Implicit Grid),其大小由 grid-auto-rows / grid-auto-columns 决定。

:定义 3 行 2 列((3 \times 2 = 6) 个格子),第 7 个元素如果仍在网格流中,就会触发隐式轨道生成。

通过网格线编号放置元素,常用属性:

  • grid-column: <start> / <end>;
  • grid-row: <start> / <end>;

关键点startend 指的是“线”,不是“格子”。

基于线的命名元素放置

除了数字编号,也可以给网格线命名,然后按名称放置,更利于维护复杂布局:

  • grid-template-columns/rows 中用 [] 命名网格线
  • 子项用 grid-column: left / right; 这样的方式引用

基于线的 span,行/列占用网格

span 表示“跨越多少个轨道”,更适合做可复用的栅格规则:

  • grid-column: span 2; 表示从自动放置的位置开始,横向跨 2 列
  • grid-row: 2 / span 3; 表示从第 2 根行线开始,跨 3 行

repeat():减少重复声明

当轨道重复出现时,用 repeat() 更清晰:

  • repeat(3, 1fr) 等价于 1fr 1fr 1fr
  • repeat(12, 1fr) 常用于 12 栅格系统

minmax():定义轨道的最小/最大值

minmax(min, max) 用于限制轨道尺寸范围,常用于自适应布局:

  • minmax(200px, 1fr):最小 200px,空间足够时再按 fr 扩展
  • 搭配 auto / max-content / min-content 可以实现内容驱动的布局策略

repeat() + minmax():自适应换行布局(auto-fill / auto-fit

这是一组非常常用的响应式写法(卡片列表、图片墙等):

  • auto-fill:尽可能“填满”轨道,即使某些轨道为空也保留占位
  • auto-fit:尽可能“贴合”内容,把空轨道折叠,让已有列拉伸占满

一个典型例子:

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

网格模拟定位

通过精确控制网格线区间,可以实现类似“定位”的效果(但仍保留 Grid 的对齐与自适应能力)。适合做规则化的“拼版布局”。

span / grid-area 组合写法

grid-area 是一个简写:

  • grid-area: row-start / column-start / row-end / column-end;

当你需要同时控制行与列的跨度时,它会比分别写 grid-row/grid-column 更集中。

栅格系统

Grid 很适合做“栅格系统”(类似设计稿中的列网格)。常见做法是定义固定列数(如 12 列),再让元素按列跨度占位。

grid 布局练习一

练习题建议关注:

  • 是否能用区域命名提升可读性(grid-template-areas
  • 是否能用 repeat() / minmax() 让布局更弹性

grid 布局练习二(仿小米商城菜单)

这个练习更贴近真实业务 UI,建议重点练:

  • 网格项对齐place-items/place-content
  • 隐式网格带来的高度控制(grid-auto-rows
  • 复杂结构时如何避免“魔法数字”的网格线编号(考虑命名线或区域)