← 返回博客
·前端工具

CSS Grid 布局完全指南:从入门到实战

CSS Grid 是强大的二维布局系统。本文从基础概念到高级技巧,带你全面掌握 Grid 布局,并配有大量实战代码示例。

#CSS#Grid#布局#前端开发

为什么是 Grid 而不是 Flex

Flexbox 是一维布局(要么横排要么竖排),Grid 是二维的——同时控制行和列。

实际开发中,页面整体布局用 Grid,组件内部用 Flex,两者配合着用,不是二选一。

一个典型的场景:后台管理页面的侧边栏 + 顶栏 + 内容区,用 Grid 两行两列就搞定了,用 Flex 得嵌套好几层。

基础概念

容器和项目

.container {

display: grid; /* 生成块级网格 */

/* display: inline-grid; 行内网格 */

}

直接子元素自动成为网格项目(grid item),跟 Flex 一样。

网格线(Grid Lines)

Grid 最核心的概念。网格线是用数字编号的,从左上角开始,列线 1、2、3...,行线 1、2、3...

后面所有的定位都是基于这些线编号来的。

定义行和列

grid-template-columns / grid-template-rows

.container {

display: grid;

grid-template-columns: 200px 1fr 300px;

grid-template-rows: 60px 1fr 40px;

}

上面这个定义:3列(固定200、自适应、固定300)+ 3行(固定60、自适应、固定40),典型的后台布局。

repeat() 函数

写一堆重复值太烦,用 repeat()

.container {

/* 4 列,每列 1fr */

grid-template-columns: repeat(4, 1fr);

/* 等价于:200px 200px 200px 1fr 1fr */

grid-template-columns: repeat(3, 200px) repeat(2, 1fr);

}

minmax() 函数

设置最小值和最大值,自适应布局非常有用:

.container {

/* 每列最小 200px,最大 1fr(等分) */

grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));

}

这行代码实现了一个**响应式网格**:容器变窄时自动减少列数,不用写媒体查询。

项目定位

按网格线定位(最常用)

.sidebar {

grid-column: 1 / 2; /* 占第1根列线到第2根列线(即第1列) */

grid-row: 2 / 3; /* 第2行 */

}

.main {

grid-column: 2 / 4; /* 占第2、3列 */

grid-row: 2 / 3;

}

.header {

grid-column: 1 / 4; /* 横跨所有列 */

grid-row: 1 / 2;

}

简写方式 grid-column: 1 / 3 意思是"从列线1开始,到列线3结束",占两列。

grid-area(语义化命名)

先给容器定义区域名称:

.container {

display: grid;

grid-template-columns: 200px 1fr;

grid-template-rows: 60px 1fr 40px;

grid-template-areas:

"header header"

"sidebar main"

"footer footer";

}

然后项目直接声明自己属于哪个区域:

.header { grid-area: header; }

.sidebar { grid-area: sidebar; }

.main { grid-area: main; }

.footer { grid-area: footer; }

这种写法可读性非常好,布局变更时只改 grid-template-areas 那几行字符串就行,不用改每个项目的定位。

间距和对齐

gap(间距)

以前用 grid-gap,现在标准属性是 gap(Flexbox 也能用):

.container {

gap: 16px; /* 行列间距都是 16px */

/* gap: 16px 24px; 行间距 16px,列间距 24px */

}

不用再写 margin 模拟间距了,Grid 原生支持。

容器内对齐(justify-content / align-content)

当网格总尺寸小于容器时生效:

.container {

justify-content: center; /* 水平居中 */

align-content: center; /* 垂直居中 */

}

可选值:startendcenterspace-betweenspace-aroundspace-evenly

项目内对齐(justify-self / align-self)

控制单个项目在自己的网格区里怎么对齐:

.item {

justify-self: center; /* 水平居中 */

align-self: center; /* 垂直居中 */

}

实战:后台管理布局

.app {

display: grid;

grid-template-columns: 240px 1fr;

grid-template-rows: 56px 1fr 48px;

grid-template-areas:

"header header"

"sidebar main"

"footer footer";

height: 100vh;

}

.header { grid-area: header; background: #001529; color: #fff; }

.sidebar { grid-area: sidebar; background: #f0f2f5; }

.main { grid-area: main; padding: 24px; overflow: auto; }

.footer { grid-area: footer; border-top: 1px solid #e8e8e8; }

HTML 结构只需要:

<div class="app">

<header class="header">顶栏</header>

<aside class="sidebar">侧边栏</aside>

<main class="main">内容区</main>

<footer class="footer">底栏</footer>

</div>

没有嵌套 div,没有 float,没有 calc——这就是 Grid 的优势。

实战:响应式卡片列表

.card-list {

display: grid;

grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));

gap: 16px;

padding: 24px;

}

/* 不需要媒体查询! */

/* 屏幕够宽时自动显示更多列 */

auto-fillauto-fit 的区别:

  • `auto-fill`:尽量填充列,即使没内容也保留空轨道
  • `auto-fit`:空轨道会收缩,内容会拉伸
  • 一般用 auto-fit 体验更好。

    常见坑

    坑1:项目溢出网格

    如果项目定位超出了定义的网格,Grid 会自动生成隐式网格轨道,但尺寸默认是 auto(内容撑开),可能很丑。

    解决方法:设置 grid-auto-rowsgrid-auto-columns 指定隐式轨道大小:

    .container {

    grid-auto-rows: minmax(100px, auto);

    }

    坑2:fr 单位没想象中智能

    1fr 是"剩余空间等分",不是"平分容器"。如果某个项目内容特别长,1fr 的列会被撑开,剩下的才参与等分。

    坑3:IE11 不支持

    如果你还要兼容 IE11——那就别用 Grid,或者做好降级(Grid 不生效时 fallback 到 Flexbox)。


    总结

    Grid 最擅长的是**页面级整体布局**和**二维对齐场景**。记住几个核心属性就能应付大部分需求:

  • `grid-template-columns / rows`——定义轨道
  • `grid-area` + `grid-template-areas`——语义化布局
  • `gap`——间距
  • `auto-fill / auto-fit` + `minmax()`——响应式
  • > **Pro Tip**: Chrome DevTools 的 Layout 面板可以可视化网格线编号,调试 Grid 布局时开着,不用自己数线号。