06Grid 网格布局
Flex 管「一条线」,Grid 管「一张网」:行和列同时定义, 子项一个个放进格子里——二维布局的终极答案。 整页骨架、相册、仪表盘,从此不用任何 hack。
一、Flex vs Grid:怎么选
两个都是现代布局主力,维度不同、分工不同。先用一张表建立全局观, 之后写页面先问自己一句:我是在排一条线,还是在铺一张网?
| 对比项 | Flex 弹性盒 | Grid 网格 |
|---|---|---|
| 维度 | 一维(一行或一列) | 二维(行 + 列) |
| 思维 | 从「内容」出发,排队伸缩 | 从「容器」出发,先画格子再放东西 |
| 子项位置 | 沿主轴依次排,不看行也不看列 | 可以指定「第几行第几列」「跨几格」 |
| 适合 | 导航栏、按钮组、一行卡片、垂直居中 | 整页骨架、相册、日历、仪表盘 |
| 能混用吗 | 完美配合:Grid 排大框架,每个格子里再用 Flex 排细节 | |
二、display: grid 与网格基本概念
在容器上写 display: grid,它就成了网格容器,
直接子元素成为网格项目。先用几个术语把地图画清楚:
- 轨道(track):一行或一列的统称,由
grid-template-columns / grid-template-rows定义; - 单元格(cell):行和列交叉出的小格子;
- 网格线(grid line):格子的边线,编号从 1 开始——竖线从左往右数,横线从上往下数,第 4 节定位全靠它;
- 网格区域(area):由若干格子拼成的大块,可以命名(第 5 节)。
只定义列、不指定位置时,项目会自动摆放:从左到右、放满一行换下一行,跟流水线一样。
grid-template-rows 写死两行高度:把下面舞台的 grid-template-rows 删掉,两行立刻变回内容撑开display: inline-grid 可以让网格容器本身行内化,道理同 inline-flex。三、轨道尺寸六种写法
grid-template-columns 的每一列,都能用不同单位描述。这六种写法覆盖了 99% 的场景:
| 写法 | 含义 | 典型用途 |
|---|---|---|
| 90px | 固定 90 像素,多一分不少 | 固定侧栏、图标列 |
| 50% | 容器宽度的 50% | 简单两栏 |
| 1fr | 可用空间切成几份,占一份 | 等宽 / 按比例分栏 |
| auto | 按内容自适应宽窄 | 「这一列包住内容就行」 |
| minmax(100px, 1fr) | 最小 100px、最大 1fr 的弹性范围 | 防压坏内容 |
| repeat(3, 1fr) | 把 1fr 1fr 1fr 写三遍的简写 | 等分多列 |
.fr 的 1fr 2fr 1fr 改成 1fr 1fr 1fr,中间的 2fr 立刻变细fr = fraction(份数),思路和 Flex 的 grow 一样:
先扣掉固定尺寸的列和 gap,剩下的空间再按份数切。
所以 200px 1fr 1fr 的意思是「先留 200px,剩下一人一半」。四、网格线定位:grid-column / grid-row
Grid 最强大的地方:想让某个项目「从第 1 条竖线到第 3 条竖线、从第 1 条横线到第 3 条横线」,直接写。
语法是 起始线 / 结束线,编号从 1 开始;也可以用 span n 表示「从当前位置跨 n 格」。
.hero 的 grid-column: 1 / 3 改成 1 / 2,它立刻缩回一列宽.wide 的 grid-column: span 2 改成 span 3,它立刻占满整行grid-column: 1 / 3 与
grid-column: span 2 在起点恰好是 1 时结果相同,起点不同就不同。
另外「结束线 = 起始线 + 跨越数」,想不通就在纸上画格子。五、命名区域:grid-template-areas
逐个数线太累?把布局画成 ASCII 图直接写进 CSS:
grid-template-areas 用字符串描述每一行,每个名字是一块区域,
项目再用 grid-area: 名字 报到。整页骨架的首选写法。
"nv mn" 和 "ft ft" 两行顺序对调,页面立刻上下翻过来.(如 "hd hd" ". mn")。六、隐式轨道与自动流:grid-auto-rows / grid-auto-flow
项目比定义的格子多怎么办?Grid 会自动补轨道(叫隐式轨道):
行方向默认按内容高、列方向默认按内容宽。grid-auto-rows / grid-auto-columns
就是给这些「计划外轨道」定尺寸的;grid-auto-flow 则决定自动摆放的方向。
| 属性 | 含义 | 关键点 |
|---|---|---|
| grid-auto-rows | 隐式行的高度 | 项目超出定义行时自动补高 |
| grid-auto-columns | 隐式列的宽度 | 同理,补列时生效 |
| grid-auto-flow | row(默认)按行填 / column 按列填 / row dense · column dense 回头填坑 | dense 会把前面空的小格塞满 |
grid-auto-rows 改成 30px,多出的行立刻变矮grid-auto-rows: 10px + 每张图
grid-row: span n 的组合控制精确行数;另有取值 dense
(写成 grid-auto-flow: row dense)会让浏览器「回头填坑」,把前面留下的小空格塞满。七、对齐全家桶:items 管格子内,content 管整张网
Grid 的对齐比 Flex 多一层——因为它有两层空间:项目在「单元格内」的位置, 以及「整张网格」在容器里的位置。记住两条名字规律就不混:
justify-items / align-items—— 项目在自己的格子里怎么摆(水平 / 垂直);justify-content / align-content—— 整张网格在容器里怎么摆(轨道有剩余空间时才看得出效果);place-items / place-content—— 上面两个的「竖写简写」:place-items: 垂直 水平。
| 作用层次 | 水平 | 垂直 | 竖写简写 |
|---|---|---|---|
| 项目在格子内 | justify-items | align-items | place-items |
| 整张网格在容器内 | justify-content | align-content | place-content |
| 单个项目覆盖 | justify-self | align-self | — |
.place 的 place-items: center 改成 place-items: end end,文字立刻滑到右下角.p3 的 align-content: end 改成 start,它立刻弹回顶部justify-self / align-self(覆盖容器设置),和 Flex 的 align-self 同理。
默认值都是 stretch:所以 Grid 项目不写宽高时,默认就撑满整个格子。八、经典实战:响应式卡片墙与日历
两个 Grid 招牌菜。卡片墙的精髓是
repeat(auto-fill, minmax(108px, 1fr)):
「每列至少 108px,能塞几列塞几列,剩下的空间平分」——零媒体查询的响应式。
minmax(108px, 1fr) 里的 108px 改成 180px,一行能放的卡片立刻变少.first 的 grid-column: 5 改成 2,整个月立刻从周二开头九、Grid 属性速查表
把整章用到的容器与项目属性归拢到两张表,之后写 Grid 忘哪个查哪个。
| 属性 | 作用 | 常见取值 |
|---|---|---|
| grid-template-columns | 定义列轨道 | px / % / fr / auto / minmax() / repeat() |
| grid-template-rows | 定义行轨道 | 同上 |
| grid-template-areas | 用 ASCII 图命名区域 | 「hd hd」…+ 句点表示空 |
| grid-auto-rows | 隐式行高度 | 如 44px |
| grid-auto-columns | 隐式列宽度 | 长度值 |
| grid-auto-flow | 自动摆放方向 | row / column / dense |
| gap | 行列间距 | row-gap / column-gap 分开设 |
| justify-items / align-items | 项目在格子内对齐 | start / center / end / stretch |
| justify-content / align-content | 整张网格在容器内对齐 | + space-between 等 |
| place-items / place-content | 上面两组竖写简写 | place-items: 垂直 水平 |
| 属性 | 作用 | 取值 |
|---|---|---|
| grid-column | 水平定位(线号 / span) | 1 / 3 · span 2 |
| grid-row | 垂直定位(线号 / span) | 1 / 3 · span 2 |
| grid-area | 抱一个命名区域 | 区域名 / 四项线号缩写 |
| justify-self / align-self | 覆盖容器的格子内对齐 | start / center / end / stretch |
十、本章小结 · 布局模块收官
至此,六种布局手段全部到手:文档流 → 浮动(读懂老代码)→ 定位(叠放钉住)→ 溢出(收拾残局)→ Flex(一维排队)→ Grid(二维铺格)。 实战中 90% 的页面 = Grid / Flex 搭框架 + 定位做点缀:
- 整页骨架:
grid-template-areas画头 / 身 / 脚、边栏 + 主区; - 格子内部:导航、按钮组、卡片行交给 Flex;
- 点睛之笔:角标、吸顶、弹层交给定位;
- 长内容:省略号、滚动区交给 overflow。
repeat(auto-fill, minmax(…)) 铺一排响应式商品卡,
卡片内部价格和销量用 Flex 两端对齐,卡片右上角再用定位加一个「热销」角标。
四种手段各就各位,布局模块就真正毕业了。