写过 flex 布局的人都踩过这个坑——最后一行只有两个格子,整个页面看起来歪了。今天 Chrome 150 用一个关键字把这件事彻底原生化了。
flex 布局用了这么多年,有个问题一直没人彻底解决:多行 flex 项目分布不均。想象一个商品列表,8 个商品排成 3 行,前两行各有 3 个,最后一行只有 2 个,整行左边空着一大块,怎么看怎么别扭。解决方案?要么靠 JS 算每行放几个,要么硬塞占位 div,没有原生 CSS 方案。
Chrome 150 引入了 flex-wrap: balance,专门解决这个问题。
核心用法
flex-wrap: balance 的逻辑很简单:把所有行尽量均匀分布,让每行的项目数相差不超过 1。用法和普通 flex-wrap: wrap 一模一样,只是换了个关键字。
.product-grid {
display: flex;
flex-wrap: balance; /* 一行代码,替代 JS 计算 */
gap: 16px;
}
这样每行会尽量放一样多的商品,最后一行如果放不下,会自动往前挪,确保每行的项目数差距最小。
三种模式
flex-wrap 属性现在有三种值可选:
| 值 | 行为 | 适用场景 |
|---|---|---|
wrap |
按顺序排列,不干预分布 | 固定顺序优先 |
balance |
均匀分布,最后一行可以少 | 商品卡片、图库网格 |
wrap-reverse |
反向换行 | 特殊布局需求 |
balance 特别适合这种场景:8 个商品,3 行,每行 ~2-3 个,balance 会让第一行放 3 个、第二行 3 个、第三行 2 个,而不是让第三行孤零零地只放 2 个。
渐进增强写法
目前 flex-wrap: balance 只有 Chrome 150+ 和 Edge 150+ 支持,全球覆盖率约 59%。但因为 CSS 无效值会被浏览器忽略,可以安全地写渐进增强:
.product-grid {
display: flex;
flex-wrap: wrap; /* 兜底 */
flex-wrap: balance; /* Chrome 150+ 生效,忽略旧浏览器 */
gap: 16px;
}
也可以用 @supports 做更明确的判断:
.product-grid {
display: flex;
flex-wrap: wrap;
gap: 16px;
}
@supports (flex-wrap: balance) {
.product-grid {
flex-wrap: balance;
}
}
两种写法效果一样,选哪个都行。第一种更简洁,第二种更显式。
实际效果对比
用 CodePen 跑一下就能看到明显区别:
<div class="grid">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
</div>
/* 普通 wrap:最后一行 2 个,左边空一大块 */
.grid-wrap {
display: flex;
flex-wrap: wrap;
gap: 12px;
}
/* balance:最后一行 3 个,分布均匀 */
.grid-balance {
display: flex;
flex-wrap: balance;
gap: 12px;
}
Chrome DevTools 打开就能看到两种布局的区别。balance 让整个网格看起来更整洁,不会出现”收尾”太单薄的问题。
局限性
flex-wrap: balance 适合每行项目数量接近的情况,但有几个限制需要注意:
浏览器支持:目前只有 Chrome/Edge 150+ 支持,Firefox 和 Safari 还不支持。如果用户群体中 Firefox 占比较高,需要确认兼容性可接受。
性能:对于超长列表(几百个项目),balance 算法可能比普通 wrap 稍慢,因为需要先预排布才能决定分布。不过对于常规的几十个项目列表,这种性能差异可以忽略。
不适合的场景:如果每行项目数必须有明确边界(比如固定每行 4 个),balance 反而会帮倒忙,因为它会自动调整每行数量。这时用 wrap 加媒体查询控制列数更合适。
什么时候用它
三个判断标准:
- 每行项目数可以略有差异:商品卡片、标签云、图库网格,这类场景适合 balance
- 视觉效果比精确控制更重要:想让整个网格看起来均匀,而不是强制每行数量一致
- 用户浏览器覆盖率可接受:59% 的全球覆盖率,对于面向技术读者的站点通常没问题
不满足这三个条件,就用普通的 flex-wrap: wrap 加 @media 控制列数。
下一步:如果你的项目里有 flex 商品列表、图库、标签云等类似布局,加一行 flex-wrap: balance 试试,看视觉效果是否改善。记住先做好 @supports 渐进增强,这样旧浏览器用户也不会受影响。
评论区
登录后可评论。