← 返回题目列表

CSS Grid 和 Flex 有什么区别?什么时候用 Grid?

高频 中等 第 12 / 28 题 更新于 2026/07/27
CSSGridFlex布局

简化版

Flex 是一维布局,主要处理一行或一列;Grid 是二维布局,可以同时控制行和列。页面整体网格、卡片矩阵、复杂区域排版更适合 Grid,组件内部线性排列更适合 Flex。

详细版

Grid 的核心概念包括:

  • Grid Container:设置 display: grid 的容器。
  • Grid Item:容器的直接子元素。
  • 行和列:通过 grid-template-columnsgrid-template-rows 定义。
  • 网格线和区域:可以用线号或 grid-template-areas 放置元素。
  • 间距:用 gap 设置。

典型写法:

.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 16px;
}

这段代码能实现响应式卡片网格:容器宽时多列,窄时自动减少列数。面试回答时可以说:Flex 更像“排队”,Grid 更像“铺棋盘”。

完整版教学

一、Flex 和 Grid 的核心差异

Flex 的思路是先选一条主轴,然后把子项沿主轴排列。它也能换行,但换行后的每一行更像独立的 flex line,行与行之间不是一个完整二维系统。

Grid 的思路是先定义一个网格,再把元素放到网格里。它天然知道行和列,所以更适合整体布局。

二、Grid 的常见工程场景

响应式卡片列表是 Grid 的经典场景:

.list {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 20px;
}

minmax(220px, 1fr) 表示每列最小 220px,最大平分剩余空间;auto-fit 表示能放几列就放几列。这样不需要写一堆媒体查询。

页面框架也适合 Grid:

.page {
  display: grid;
  grid-template-columns: 240px minmax(0, 1fr);
  gap: 24px;
}

左侧固定导航,右侧自适应内容,非常清楚。

三、Grid areas 提升可读性

复杂页面可以用区域命名:

.layout {
  display: grid;
  grid-template-areas:
    "header header"
    "sidebar main"
    "footer footer";
  grid-template-columns: 220px 1fr;
}

这种写法可读性很好,一眼能看出页面结构。缺点是动态布局特别复杂时,维护 areas 可能变麻烦。

四、选择标准

判断标准很简单:如果布局重点是一条轴上的对齐和伸缩,用 Flex;如果重点是行列关系、二维分区或响应式网格,用 Grid。

实际工程里两者常常配合使用:页面大结构用 Grid,卡片内部、按钮组、导航菜单用 Flex。这不是二选一,而是分工。

五、面试追问与工程落地

Grid 常见追问是 auto-fitauto-fill 的区别。两者都会尽量创建可容纳的列,但当有空轨道时,auto-fit 会折叠空轨道,让已有列拉伸占满空间;auto-fill 会保留空轨道位置。卡片自适应列表里通常更常用 auto-fit

另一个工程重点是 minmax(0, 1fr)。在 Grid 或 Flex 中,内容默认最小尺寸可能撑开轨道,导致 1fr 看起来“不听话”。使用 minmax(0, 1fr) 可以明确允许轨道缩小到 0,避免长文本或表格把布局撑爆。

Grid 也不意味着完全不需要媒体查询。对于简单卡片矩阵,repeat(auto-fit, minmax()) 很强;但对于页面信息架构变化,比如移动端侧栏变顶部、左右布局变上下布局,媒体查询仍然是清晰的断点表达。

六、用容器宽度推导自动列数

设容器宽 800px,列间距 20px,轨道写成 repeat(auto-fit, minmax(240px, 1fr))。放 3 列至少需要 3 × 240 + 2 × 20 = 760px,能容纳;放 4 列至少需要 4 × 240 + 3 × 20 = 1020px,因此本例最多 3 列。扣除 gap 后的 760px 轨道空间再由三个 1fr 分配,每列约 253.33px

概念GridFlex
主要建模行列二维轨道单条主轴及多条独立 flex line
空间入口先定义轨道,再放项目先取项目基础尺寸,再分剩余空间
典型自适应auto-fit + minmax()flex-wrap + flex-basis
视觉重排风险显式放置或 dense 可能改视觉顺序order、反向轴可能改视觉顺序

auto-fillauto-fit 在计算能容纳多少重复轨道时相近,差异出现在放置项目后:auto-fit 会折叠空的重复轨道,已有列因而能拉伸;auto-fill 保留空轨道。选择它们取决于空位是否应该继续占据网格结构,而不是固定背某一个“更好”。

1fr 写在轨道外部时隐含自动最小值,长内容可能把轨道撑开;需要明确允许收缩的主内容列时,minmax(0, 1fr) 通常比裸 1fr 更稳。

七、常见误区与追问

  • 误区:用了 Grid 就绝对不需要媒体查询。 自动轨道能处理尺寸伸缩,但信息架构从侧栏变顶部等模式切换仍适合用断点表达。
  • 误区:Flex 能换行,所以它与 Grid 都是同一种二维布局。 Flex 每条线独立分配主轴空间,Grid 的项目共享统一的行列轨道。
  • 误区:1fr 永远等于容器宽度的一个平均份额。 它分的是扣除固定轨道、gap 等后的可分配空间,还会受轨道自动最小尺寸和内容贡献影响。
  • 追问:auto-fitauto-fill 的核心区别是什么? 项目放置后,前者折叠空重复轨道,后者保留空轨道位置。
  • 追问:为什么 minmax(0, 1fr) 能缓解长文本溢出? 它把轨道最小值明确设为零,不再让隐含的 auto 最小值优先保留内容最小宽度。
  • 追问:grid-auto-flow: dense 有什么代价? 它会回填较早的空洞,视觉顺序可能与 DOM 顺序不同,必须评估阅读和键盘导航体验。
  • 追问:页面布局能否外层 Grid、组件内部 Flex? 可以,两者解决的层次不同,这种组合正是常见工程用法。

八、加强记忆

Flex 像“队伍”,关心队伍方向、间距、对齐;Grid 像“棋盘”,先画行列,再把元素放进格子。遇到二维布局优先想 Grid,遇到单行单列对齐优先想 Flex。