CSS Grid 布局入门:二维网格排版实战
做页面排版时,很多人先想到一维布局:横着排一排,或者竖着排一列。遇到既要控制行、又要控制列的页面,比如管理后台、卡片墙、图文混排的首页,一维布局很快就会显得吃力。CSS Grid 就是为二维排版而生的布局方式,它让我们可以同时在行和列两个方向上安排元素的位置,写起来也更直观。本文用一个完整的小例子,带你从零上手 Grid。
一、Grid 解决什么问题
想象你要做一个三列的卡片列表,每行三个卡片,卡片之间留出均匀间距,窗口变窄时自动变成两列。只用一维布局,你需要不断计算宽度和换行,间距也容易对不齐。用 Grid,只需要告诉容器一句话:分成三列,列与列之间留出间距。行方向由内容自然撑开,浏览器会帮你把卡片一个一个放进格子里。
Grid 的核心思想是先画格子,再放东西。容器负责定义网格:有几行、几列、每行每列多宽;项目负责说自己待在哪个格子,或者交给浏览器自动排列。理解了这两层,Grid 就掌握了一大半。
二、核心概念:容器与项目
给一个元素设置成网格容器后,它的子元素自动成为网格项目。注意这个关系只有一层:孙子元素不会自动成为项目,需要单独再设置。
容器上常用的属性有三个:
- 划分列:决定网格有多少列,每列多宽
- 划分行:决定网格有多少行,每行多高
- 间距:行与行、列与列之间的空隙
项目上常用的属性也有三个:
- 占哪几列:从第几条列线开始,到第几条列线结束
- 占哪几行:从第几条行线开始,到第几条行线结束
- 在格子里的对齐方式:水平居中、垂直居中,或者拉伸填满
网格线是理解 Grid 的关键。画三列,会出现四条垂直方向的列线,编号从 1 到 4;画两行,会出现三条水平方向的行线。说一个项目从第 1 条列线跨到第 3 条列线,就是它占了前两列。
三、第一步:把容器变成网格
下面是最简单的三列布局:
.container {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
gap: 16px;
}
display 的值设为 grid,容器就变成了网格。grid-template-columns 的三个 1fr 表示三列,每列占一份可用空间,fr 是 Grid 里的弹性单位,类似把剩余空间按份数分配。gap 是行间距和列间距的合写,16 像素的间距会自动加在格子之间,不需要再给每个卡片写外边距。
把子元素放进容器,它们会按顺序自动落入格子:第一个进第一行第一列,第二个进第一行第二列,第四个自动换到第二行第一列。大部分简单场景下,你甚至不需要给项目写任何定位代码。
四、列宽的几种常用写法
固定宽度适合尺寸明确的区域,比如侧边栏写 240 像素,主内容区写 1fr,剩下的空间自动归主内容区。百分比也可以用,但 fr 更推荐,因为它已经把间距算在内,不容易因为间距导致溢出。
repeat 可以少写很多重复值:
.container {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 16px;
}
这一行和上面三列的写法完全等价。想让列数随窗口宽度自适应,可以用自动填充配合最小宽度:
.container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
gap: 16px;
}
auto-fit 的意思是能放几列就放几列,每列至少 240 像素,空间有多余时再按比例拉伸。窗口宽了是四列,窄了自动变两列或一列,一行代码就做到了响应式,这也是 Grid 最受欢迎的写法之一。
行高通常不需要逐行写死。内容本身有高度时,行高由内容撑开;想统一行高,可以用 auto-rows 指定,比如每一行至少 180 像素,内容多了再自动长高。
五、精确放置项目:线编号与区域命名
自动排列够用了,但有些位置需要精确定位,比如首页的大横幅要横跨三列,侧边栏要从第一行跨到第三行。这时给项目写定位:
.banner {
grid-column: 1 / 4;
grid-row: 1 / 2;
}
.side {
grid-column: 3 / 4;
grid-row: 2 / 4;
}
grid-column 的两个数字是起始列线和结束列线,1 到 4 就是横跨全部三列。用 span 的写法更直观,grid-column 后面写 span 2,表示这个项目横跨两列,不需要再数线号。
如果页面结构固定,用区域命名可读性更好。先给容器画一张区域图:
.page {
display: grid;
grid-template-columns: 240px 1fr;
grid-template-areas:
"head head"
"nav main"
"foot foot";
gap: 16px;
}
再让每个项目认领自己的区域名:
.header { grid-area: head; }
.nav { grid-area: nav; }
.main { grid-area: main; }
.footer { grid-area: foot; }
这样只看区域图就能知道页面长什么样,改布局时也只需要改这张图。区域图里每一行引用的名字数量要和列数一致,名字相同的格子会自动连成一片。
六、实战:做一个图文卡片墙
把前面的知识拼起来,做一个常见的卡片墙:顶部一个横幅,下面是自动换列的卡片。
容器先分三列,横幅横跨三列,卡片交给自动排列:
.wall {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
gap: 16px;
}
.banner {
grid-column: 1 / -1;
}
这里的负数线号很好用,负 1 表示最后一条线,1 到负 1 就是从头跨到尾,不管实际有几列都成立。卡片内部再用一块小网格排布图片和文字,图片占满整行,标题和描述各占一行,结构非常清晰。
对齐也很简单。想让卡片里的内容都水平居中,给容器写 justify-items,取值为居中;想让所有卡片沿垂直方向居中,用 align-items。需要整个网格在页面里居中时,用 justify-content 控制。默认情况下项目会拉伸填满格子,这也是卡片等高的原因:同一行里最高的卡片决定行高,其他卡片自动拉伸到同样高度。
七、容易踩的几个坑
第一个坑是只给项目写了定位,忘记给容器写 display 的网格声明,定位属性不会生效。先确认容器已经是网格,再检查项目。
第二个坑是列宽写得太死。全部写固定像素时,小屏幕上很容易横向溢出。内容区优先用 fr,侧边栏再用固定宽度;需要自适应时优先用自动填充加最小宽度。
第三个坑是把 Grid 和一维布局混淆。Grid 适合整体骨架和二维排列,按钮组、导航栏这种单行排列,用一维布局更顺手。两者不是非此即彼,页面骨架用 Grid,骨架里面的小组件用一维布局,是最常见的组合。
第四个坑是隐式网格。项目数量超过了你画的格子时,浏览器会自动生成新的行来放它们。自动生成的行高可能不符合预期,提前用 auto-rows 给隐式行定一个合理的最小高度,页面会稳定很多。
八、小结与练习
CSS Grid 的学习路径可以概括为四步:先把容器变成网格,再用列定义分出格子,然后让项目自动排列,特殊位置再用线编号或者区域命名精确定位。掌握这四步,常见的管理后台、卡片墙、图文混排页面都能应对。
建议做一个小练习验证掌握程度:用 Grid 搭一个三栏页面,左侧是固定宽度的导航,中间是自适应宽度的内容区,右侧是一个活动卡片区;再给内容区做一个自动换列的卡片墙,窗口变窄时列数随之减少。能独立写出这个页面,Grid 就算入门了。之后再去探索对齐细节和子网格,会发现更多排版上的自由度。
- 点赞
- 收藏
- 关注作者
评论(0)