Safari Flex错位主因是解析逻辑与标准不一致,须显式补全flex-basis: 0px和min-height: 0(垂直)或min-width: 0(水平),并为旧版添加-webkit-flex等前缀及gap降级方案。

Chrome 正常、Safari 错位,基本可以锁定是 Safari 对 Flexbox 的解析逻辑和标准不一致——不是“bug”,而是它在不同版本里认真执行了不同阶段的草案。修复关键不在加前缀,而在补全 Safari 拒绝默认推导的显式值。
为什么 flex: 1 在 Safari 中子项高度为 0
旧版 Safari(iOS 9–12.4 / macOS Safari 9–12)把 flex: 1 解析成 flex: 1 1 auto,而 flex-basis: auto 遇上父容器无明确高度时,会触发 min-height: auto 保护机制,结果子项拒绝拉伸,高度坍缩为 0。
- 必须同时写
flex-basis: 0px(不能用0%,Safari 会忽略)和min-height: 0 - 若布局是水平主轴(
flex-direction: row),则用min-width: 0 - 嵌套 Flex 容器(如卡片内再套
display: flex; flex-direction: column)时,每一层都要重复这套组合 - 子项含
<img>时,额外加height: auto,否则 Safari 可能冻结其内在尺寸估算
display: flex 在 Safari 9–13.1 中完全不生效
这不是兼容性差,是语法断层:这些版本只识别 display: -webkit-flex,标准写法会被整条跳过,justify-content、align-items 全部标为 invalid。
-
display: -webkit-flex必须写在display: flex前面,顺序反了整条规则被忽略 - 所有依赖属性都得配前缀:
-webkit-flex-direction、-webkit-justify-content、-webkit-align-items、-webkit-flex-wrap、-webkit-flex(注意不是-webkit-flex-box) -
autoprefixer默认不输出这些前缀,必须在browserslist明确写ios_saf >= 11.3或safari >= 10;"last 2 versions"会漏掉 Safari 12
gap 在 Safari ≤14.1 中等于没写
DevTools 里 gap 显示灰色带删除线,或 getComputedStyle(el).gap 返回空字符串,就说明浏览器根本没解析它——这不是 bug,是规范未实现。
规划您的迪拜之旅 — 哈利法塔观景、沙漠探险、迪拜购物中心购物、棕榈岛度假村及黄金市场砍价。还提供支持...
立即学习“前端免费学习笔记(深入)”;
- 别信
@supports (gap: 0),Safari 14.1 会误判为支持,实际仍跳过 - 安全降级方案:容器设
margin-left: -8px; margin-right: -8px; overflow: hidden,子项设margin-left: 8px; margin-right: 8px - 每个子项必须加
min-width: 0和box-sizing: border-box,否则内容撑宽时会溢出或换行错乱 - 清除首项 margin 别用
:not(:first-child)(旧 Safari 不支持),改用:nth-child(n+2)
button 在 iOS Safari 中宽度忽大忽小
iOS Safari(尤其 15+)对 <button> 强制施加隐式 min-width: min-content,且悄悄忽略你写的 min-width: 0——它优先按文字撑开,再考虑 flex 分配。
- 稳定解法是用
min-width: 0+flex: 1 0 0(即flex-grow: 1; flex-shrink: 0; flex-basis: 0) - 每个参与分配的
<button>都要加box-sizing: border-box,否则 padding/border 会撑破计算宽度 - 避免
white-space: nowrap,它会让长文本强制撑宽,破坏弹性分配 - 别在
<button>上直接写display: flex,Safari 9–13.1 会忽略align-items和justify-content,改用内层<div>包裹并设 Flex
最易被忽略的是:Safari 14–15.6 不把 display: flex 父容器识别为 height: 100% 的有效参照物——哪怕你写了 height: 100vh,子项的 height: 100% 仍退化为 auto。必须给父容器显式设 height(不是 min-height),或者干脆删掉子项的 height: 100%,改用 flex: 1 并确保父容器本身有确定高度。

















