写过 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 加媒体查询控制列数更合适。

什么时候用它

三个判断标准:

  1. 每行项目数可以略有差异:商品卡片、标签云、图库网格,这类场景适合 balance
  2. 视觉效果比精确控制更重要:想让整个网格看起来均匀,而不是强制每行数量一致
  3. 用户浏览器覆盖率可接受:59% 的全球覆盖率,对于面向技术读者的站点通常没问题

不满足这三个条件,就用普通的 flex-wrap: wrap@media 控制列数。


下一步:如果你的项目里有 flex 商品列表、图库、标签云等类似布局,加一行 flex-wrap: balance 试试,看视觉效果是否改善。记住先做好 @supports 渐进增强,这样旧浏览器用户也不会受影响。

评论区

0 条评论

登录后可评论。