阅读提要

「什么时候用 Grid,什么时候用 Flex」这个问题有确定答案:看你要解决的是一维排布还是二维关系。判断错了,代码会越写越别扭。

开始阅读

字号

一个判断标准

把它们当成两把工具:

  • Flex 管的是一条线上的分配:一排按钮怎么分空间、垂直居中、顺序调整。
  • Grid 管的是一张表里的对位:行和列同时存在,元素要跨行跨列。

判断方法:如果你能用「一排」或「一列」描述需求,用 Flex;如果需求里出现「第几列」「每行三个」「左中右三栏且中间自适应」,用 Grid。

这个判断做对了,两种布局的代码都只有几行;做错了,就会陷入「给子元素加了一堆 flex-basis 还是不齐」的泥潭。

布局能力对照

Flex 的真实边界

Flex 的核心是「按比例分配剩余空间」。它擅长:

.toolbar {
  display: flex;
  align-items: center;
  gap: 12px;
}
.toolbar .spacer { margin-left: auto; }

但它在两个场景会突然变难:

一是等宽多列。 想让子元素「每行三个、自动换行、间距一致」,用 flex-wrap + calc(33.33% - gap) 能实现,但 gap 的计算会变得很脏,而且最后一行不满时会左对齐——这通常不是你要的。

二是纵向对齐。 Flex 的 align-items 只作用于交叉轴。要让两列里的文字基线对齐,Flex 做不到,只能靠固定高度硬凑。

Grid 的杀手锏

Grid 允许直接描述「结构」:

.cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 20px;
}

这一行实现的是:每列最少 260px,能放几个放几个,剩余空间平均分。窗口变宽时列数自动增加,不需要任何媒体查询。这是 Flex 做起来最别扭、Grid 做起来最自然的事。

跨格也很直接:

.layout {
  display: grid;
  grid-template-columns: 220px minmax(0, 1fr) 180px;
  grid-template-areas: "side main toc";
  gap: 24px;
}

minmax(0, 1fr) 里的 0 很重要。写成 1fr 时,网格项的最小尺寸默认是内容尺寸,一个长 URL 或宽表格会把中间列撑破,整个布局横向溢出。这是 Grid 最常见的坑。

那个 min-width: auto 的坑

Flex 和 Grid 的子项默认 min-width: auto,意思是「不能小于内容的最小尺寸」。所以:

.row { display: flex; }
.row .text { overflow: hidden; text-overflow: ellipsis; }

这段代码不会生效——省略号出不来,因为 .text 会被内容撑开。必须显式写 min-width: 0:

.row .text { min-width: 0; overflow: hidden; text-overflow: ellipsis; }

这个问题在「左侧头像 + 右侧长文件名」的列表里几乎必现。记住一句话:只要用了 flex: 1 或 1fr 又要省略号,就先加 min-width: 0。

混用是对的,不是妥协

真实页面几乎都是混用:外层 Grid 划分区域,区域内 Flex 排一行按钮。

.page { display: grid; grid-template-columns: 240px 1fr; }
.page .header { display: flex; justify-content: space-between; }

这不是「不纯粹」,而是各取所长。反过来,硬要用 Grid 排一行按钮,或者硬要用 Flex 做三栏等高,才是给自己找麻烦。

兼容性与性能

现代浏览器的支持没有差异。唯一需要注意的是:Grid 的自动放置算法在超大数据量(几千个格子)时会有布局开销,而 Flex 在这种场景更轻。但普通页面根本到不了这个量级。

真正影响性能的是布局抖动,不是 Grid 或 Flex 的选择。避免在滚动回调里读 offsetHeight 再写样式,这条比选哪个布局重要得多。

收尾

一句话记住分工:一维用 Flex,二维用 Grid,嵌套时各管一层。

遇到「怎么都排不齐」的时候,先别改属性,先问自己是不是选错了工具。选对了,CSS 通常只有三五行。

什么时候两者都不该用

有些布局根本不需要 Flex 或 Grid:多列文本用 columns,卡片瀑布流用 CSS columns 或 masonry(逐步支持中),表格数据老老实实用 <table>。

尤其是表格。用 Grid 拼出来的「表格」在语义、可访问性、复制粘贴上都劣于原生 <table>。屏幕阅读器读不出行列关系,从网页复制到 Excel 会乱序。

判断标准是:这个内容在语义上是不是表格。是,就用 table,样式问题用 CSS 解决,不要为了「布局自由」牺牲语义。

你认为这篇文章怎么样?

还没有表情反馈

分享文章