<p>Safari 15.4前calc()嵌套会静默丢弃整条CSS声明,应改用带单位的CSS变量拆解(如--inner: calc(100% - 40px) → width: calc(var(--inner) / 3)),PostCSS不自动展开calc内var(),需手动fallback或构建时静态求值。</p>

calc()嵌套在Safari 15.4前会被整条丢弃
不是报错,也不是计算错误,而是浏览器直接跳过那行CSS声明。你在Chrome里看着好好的width: calc(calc(100% - 20px) / 3),切到iOS 15.3真机或Android 4.4 WebView,DevTools里该属性标着Invalid property value,Computed值还是初始值——布局就塌了。
用CSS变量拆解嵌套,兼容性翻倍
别硬塞两层calc(),把中间结果存成变量再引用:
-
--inner: calc(100% - 40px)→ 定义带单位的中间值 -
width: calc(var(--inner) / 3)→ 在外层引用,Safari 12+、Chrome 49+、Firefox 31+全支持 - 变量必须带单位:
--inner: 60px✅,--inner: 60❌(后者会让calc(var(--inner) + 10px)静默失效)
PostCSS不会自动展开calc里的var()
postcss-custom-properties默认只处理顶层var(--x),对calc(100% - var(--gap))这种无感。即使开了preserve: false,它也只替换background: var(--primary)这类简单声明,calc()里的var()原样保留——旧浏览器照样跳过整条规则。
真正能降级的路径只有两条:
立即学习“前端免费学习笔记(深入)”;
- 构建时用
postcss-calc静态求值(仅适用于变量值固定、无运行时依赖的场景) - 手动写fallback:先写
width: 280px,再写width: calc(100% - 40px),靠浏览器忽略不认识的值来兜底
@supports检测不出嵌套是否可用
@supports (width: calc(0px))只能确认浏览器认不认识calc()这个关键字,对calc(calc())、calc(100vh - env(safe-area-inset-bottom))这类真实失效场景完全不敏感。
真要判断,得用JS:
if (!CSS.supports('width', 'calc(calc(100% - 10px) / 2)')) {
document.documentElement.classList.add('no-calc-nest');
}然后在CSS里写.no-calc-nest .card { width: 80%; }。注意别写CSS.supports('--_'),IE会直接报错。
最常被忽略的是:嵌套失效时没有控制台提示,你得主动点开DevTools的Computed面板,看目标属性有没有被灰掉——那才是第一线索。


















