calc()中加减运算必须单位一致,仅100%±px被广泛兼容;rem、vh等混用易失败,应转为px或改用dvh;CSS变量需自带单位,0也须写0px;预处理器变量需显式插值且带单位;嵌套calc()在旧Safari中不支持。

calc()里加减运算必须单位一致
浏览器在解析calc()加减表达式时,不会自动换算单位。写calc(100% - 20px)能生效,是因为主流浏览器对“百分比 vs 像素”做了特殊兼容;但calc(1rem - 10px)在旧版 Safari 或 Android WebView 中大概率静默失败——它不是“算错”,而是直接跳过整条声明。
- 真正安全的组合只有:同类型单位(
px+px、%+%)或明确支持的跨单位(100%±px) - 想用
rem做基准?统一转成px:先定义--base: 16px,再写calc(var(--base) * 1.5 - 8px) - 避免混用
vh和px做加减,滚动时地址栏高度变化会导致100vh突变,calc(100vh - 60px)可能抖动;改用dvh更稳:calc(100dvh - 60px)
变量值必须自带单位,不能靠拼接
var(--gap)返回的是原始字符串,不是“带单位的数值”。如果--gap: 20(没单位),calc(100% - var(--gap))实际变成calc(100% - 20),浏览器无法判断这是20px还是20%,整条规则被丢弃。
- CSS 变量定义时就要带单位:
--gap: 20px✅,--gap: 20❌ - 0 也必须带单位:
top: calc(0px + 10px)✅,top: calc(0 + 10px)❌ - 乘除场景下,右操作数可以无单位(
calc(var(--width) * 2)),但左操作数仍需单位(--width: 200px)
Sass/Less变量不插值=白写
calc(100% - $gap)这种写法根本不会进入浏览器——Sass 编译器要么原样输出(浏览器看到非法 token),要么擅自计算成calc(80%)(单位丢失)。变量必须显式插值,且插值后结果得含单位。
- Sass 正确写法:
width: calc(100% - #{$gap});,且$gap: 20px(不能是20) - Less 推荐写法:
width: calc(~"100% - @{gap}");,双引号+波浪号能绕过部分 loader 的二次转义问题 - 绝对别省略空格:
calc(100% -#{$gap})输出calc(100% -20px),浏览器无视
嵌套calc()在 Safari 15.4 前完全失效
calc(calc(100% - var(--gap)) / 2)这种写法在 Safari 15.4 之前会被整个 CSS 规则静默忽略,DevTools 显示Invalid property value,控制台却没报错。这不是语法警告,是浏览器解析器直接跳过整行。
立即学习“前端免费学习笔记(深入)”;
- 拆解为中间变量:
--inner-width: calc(100% - var(--gap));,再用width: calc(var(--inner-width) / 2) - PostCSS 插件(如
postcss-custom-properties)默认不展开calc()里的var(),preserve: false只处理顶层变量,嵌套引用原样保留 - 真机调试时,iOS 15.3 和 Android 4.4 WebView 是典型“失灵区”,别依赖 Chrome 调通就认为没问题
复杂点在于三重耦合:单位缺失 + 空格遗漏 + 预处理器未插值,任意一个出错,calc()就彻底消失,连 DevTools 的 computed 栏都找不到痕迹。


















