CSS Grid 布局实战指南,看这篇就够了

上周接了个后台管理系统的活,产品甩过来一张布局截图:左侧导航固定宽度,顶部通栏,中间内容区分三栏,底部还要个跨满整行的状态栏。我当时脑子里第一反应是------这用 Flex 得嵌套多少层 div?后来切到 CSS Grid,代码量直接砍了一半。

先搞清楚 Grid 到底在干嘛

很多人一听到 Grid 就觉得是"高级 Flexbox",其实它俩解决的问题不一样。Flexbox 是一维布局,一次只能处理一行或一列。Grid 是二维布局,行和列同时控制。

你可以把 Grid 想象成 Excel 表格------你定义好几行几列,然后往格子里放东西,想跨行跨行,想跨列跨列。

先看个最基础的例子,三列等宽布局:

css 复制代码
.container {
  display: grid; /* 开启 Grid 布局 */
  grid-template-columns: 1fr 1fr 1fr; /* 三列等分,1fr 表示一份空间 */
  gap: 16px; /* 行列间距统一 16px */
}

fr 这个单位是 Grid 的核心。它代表"可用空间的一份",你写 1fr 2fr 就是第二列占第一列的两倍宽。比百分比好使多了,不用自己算剩余空间。

repeat() 函数可以简化重复写法,上面三列等宽等价于:

css 复制代码
.container {
  grid-template-columns: repeat(3, 1fr); /* 重复3次,每次1fr */
}

后台管理系统布局实战

回到开头那个需求,用 Grid 来搭后台管理系统的整体骨架,代码其实很直观。

先写个"朴素版",很多人一开始会这么干:

css 复制代码
/* 朴素写法:手动算宽度,改一个数字全局崩 */
.layout {
  display: grid;
  grid-template-columns: 240px 1fr; /* 侧边栏240px,内容区自适应 */
  grid-template-rows: 60px 1fr 40px; /* 顶部60px,内容区撑满,底部40px */
  height: 100vh; /* 撑满整个视口 */
}

这个写法能跑,但问题在于------如果你要给某个区域命名、调整顺序,全靠 grid-row 和 grid-column 的数值去定位,一改就乱。

更好的做法是用 grid-template-areas,直接"画"出布局:

css 复制代码
.layout {
  display: grid;
  /* 用字符串"画"出布局结构,每个单词对应一个区域名 */
  grid-template-areas:
    "sidebar header"   /* 第一行:侧边栏 + 顶部导航 */
    "sidebar main"     /* 第二行:侧边栏 + 内容区 */
    "sidebar footer";  /* 第三行:侧边栏 + 底部状态栏 */
  grid-template-columns: 240px 1fr; /* 侧边栏固定240px,右侧自适应 */
  grid-template-rows: 60px 1fr 40px; /* 顶60 中自适应 底40 */
  height: 100vh;
}

/* 每个子元素直接声明自己属于哪个区域,一目了然 */
.sidebar { grid-area: sidebar; }  /* 侧边栏 */
.header  { grid-area: header; }   /* 顶部导航 */
.main    { grid-area: main; }     /* 内容区 */
.footer  { grid-area: footer; }   /* 底部状态栏 */

看到区别了吧?grid-template-areas 就像在代码里画了个布局示意图,谁在哪、跨不跨行,一眼就明白。后续要调整布局,改字符串就行,子元素的 CSS 完全不用动。

如果内容区还要再细分,比如左侧列表 + 右侧详情,直接在 .main 里再嵌套一个 Grid:

css 复制代码
.main {
  display: grid;
  grid-template-columns: 1fr 1fr; /* 内容区左右各占一半 */
  gap: 12px; /* 中间留12px间距 */
  padding: 16px; /* 内边距 */
}

Grid 和 Flexbox 到底怎么选

这个问题我被问了不下十次。简单说:一维用 Flex,二维用 Grid。但实际项目里没这么非黑即白。

下面是我总结的一个对照表,基本能覆盖大部分选型场景:

场景 推荐方案 原因
导航栏内部元素排列 Flexbox 单行排列,flex 的 space-between 就够了
页面整体骨架布局 Grid 需要同时控制行和列
卡片列表(等宽自适应) Grid repeat(auto-fill, minmax(280px, 1fr)) 一行搞定
表单 label + input 对齐 Grid 两列网格天然对齐,不用算 label 宽度
居中对齐一个元素 Flexbox justify-content + align-items 最简洁
不规则瀑布流 都不太行 考虑 Masonry 布局或 JS 方案

卡片列表那个写法值得单独说一下:

css 复制代码
.card-list {
  display: grid;
  /* 每列最少280px,容器能放几列就放几列 */
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 20px; /* 卡片间距 */
}

auto-fill 的意思就是"自动填列"------容器够宽就塞新列,不够就换行。配合 minmax(280px, 1fr),每张卡片最小 280px,最大撑满剩余空间。不用写一行媒体查询就能实现响应式。

有个容易踩的坑:auto-fillauto-fit 看着差不多,行为不一样。auto-fill 会保留空列(右边可能留白),auto-fit 会把空列折叠掉让现有列撑满。大多数场景下 auto-fit 更符合预期。

几个容易忽略的实用技巧

minmax() 替代媒体查询做自适应

css 复制代码
.container {
  grid-template-columns: repeat(3, minmax(200px, 1fr)); /* 每列最小200px */
}

当容器宽度不够放三列 200px 时,Grid 会自动换行,不需要额外写 @media

place-items 一行搞定居中

css 复制代码
.container {
  display: grid;
  height: 100vh;
  place-items: center; /* 水平垂直同时居中,等价于 justify + align */
}

这比 Flexbox 的 justify-content: center; align-items: center; 还少写一行。

子元素自己控制跨列

不需要改容器定义,子元素自己声明就行:

css 复制代码
.featured-card {
  grid-column: span 2; /* 这个卡片横跨两列 */
}

.full-width-banner {
  grid-column: 1 / -1; /* 从第一列到最后一列,跨满整行 */
}

span 2 是"往右跨两列",1 / -1 是"从第一条网格线到最后一条",两种写法看场景选。

最后

用了大半年 Grid 做后台项目,几点感受:

  • Grid 做页面骨架,Flex 做组件内部排列,两者配合用才是正解
  • grid-template-areas 是后台布局的杀手锏,可读性拉满
  • repeat(auto-fit, minmax(...)) 一行代码搞定响应式卡片列表
  • 别死磕"用 Grid 还是 Flex",实际项目里嵌套着用才是常态
  • Grid 的浏览器兼容性已经没问题了,IE 不管了,放心用

你们项目里 Grid 用得多还是 Flex 用得多?评论区聊聊。

相关推荐
嘟嘟嘟95276 小时前
Spotify Honk 的启示:AI 编程日常
人工智能·程序员·ai编程
程序员cxuan6 小时前
从 0 到 1 速通 WorkBuddy
人工智能·后端·程序员
野生的码农19 小时前
5 年级的儿子居然学会了破解。。。
程序员
这个DBA有点耶1 天前
数据库教程:从零基础到实战的完整学习路径(2026版)
数据库·程序员·代码规范
kyriewen1 天前
GPT-6 拿下模型众测第一:我拆完 30 个主题的实时榜单,「最强 AI」得看你问哪个场景
人工智能·程序员·ai编程
Sam_Deep_Thinking1 天前
单一职责原则:JAVA LocalDate的设计取舍
java·后端·程序员·单一职责原则
codigger1 天前
程序员别再踩这 3 个坑——做了五年开发,我把能踩的坑全踩了一遍
后端·ai·程序员·架构·程序员职场
小酒星小杜1 天前
【AI+Gpt-Image2.5】我偷偷把同事做成了虚拟角色,结果被发现了
人工智能·程序员·产品