CSS Grid 布局入门:二维网格排版实战

举报
神的孩子都在跳舞 发表于 2026/11/11 08:35:52 2026/11/11
【摘要】 做页面排版时,很多人先想到一维布局:横着排一排,或者竖着排一列。遇到既要控制行、又要控制列的页面,比如管理后台、卡片墙、图文混排的首页,一维布局很快就会显得吃力。CSS Grid 就是为二维排版而生的布局方式,它让我们可以同时在行和列两个方向上安排元素的位置,写起来也更直观。本文用一个完整的小例子,带你从零上手 Grid。 一、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 就算入门了。之后再去探索对齐细节和子网格,会发现更多排版上的自由度。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。