最稳方案是用margin模拟gap,因Safari≤14.1、IE、Android WebView≤76等浏览器直接静默丢弃gap声明;确认不支持需三步实锤:DevTools中gap灰显或带删除线、Computed面板值为空或not supported、getComputedStyle(el).gap返回""或"normal"。

直接用 margin 模拟是最稳的路径,别等 @supports 或 PostCSS 插件兜底——那些方案在 Safari ≤14.1、IE、Android WebView 76 以前根本不可靠,gap 被解析器静默丢弃,写了等于没写。
怎么确认 gap 真的不被支持
不是看有没有效果,是看浏览器认不认识它:
- DevTools → Elements 面板里,
gap声明显示为灰色或带删除线 - Computed 面板搜
gap,值为空字符串""或标着not supported - 控制台执行
getComputedStyle(el).gap,返回""或"normal" -
@supports (gap: 0)在 Safari 14.1 下会误判为true,不能信
用 margin-left 模拟水平 gap 的硬性条件
只给非首项加左外边距,能避开换行错位、动态增删子项失效等问题,但必须满足以下四点才不出 bug:
- Flex 容器加
overflow: hidden,否则负边距可能触发意外滚动条 - 每个子项加
min-width: 0,否则长文本或图片会撑破容器宽度 - 每个子项加
box-sizing: border-box,避免padding+border导致尺寸失控 - 用
:nth-child(n+2)替代:not(:first-child),后者在旧版 Safari 和 Android WebView 中不支持
示例写法:
.flex-row { display: flex; }<br>.flex-row > * { margin-left: 12px; min-width: 0; box-sizing: border-box; }<br>.flex-row > *:nth-child(1) { margin-left: 0; }立即学习“前端免费学习笔记(深入)”;
遇到 flex-wrap: wrap 怎么办
纯 margin-left 方案会在换行后首项左侧多出间隙,这不是 bug,是布局流自然结果。解决方式取决于你是否允许 JS 参与:
- 若可用 JS:监听
resize,遍历子项用getBoundingClientRect()判断换行位置,在每行末尾插入空<div class="gap-filler"></div> - 若纯 CSS:改用
inline-block+font-size: 0消除空白符,再配vertical-align: top和margin-right,兼容性极好但失去 Flex 对齐能力 - 若已用 PostCSS:启用
postcss-gap-properties插件,但它只处理静态子项数,动态渲染场景慎用
真正容易被忽略的是 min-width: 0 —— 它几乎从不被主动写,但漏掉它,哪怕其他所有防护都加上,iOS 14.5 设备上也可能突然崩掉布局。


















