css中var()的第二个参数是回退值而非默认值,仅在变量未声明或被设为unset时生效;空字符串、initial、拼错值等已声明情况均不触发回退。

直接说结论:CSS 里没有“定义变量默认值”这回事,var() 的第二个参数不是变量的默认值,而是每次调用时的**回退值**,只在变量**完全未声明**或被设为 unset 时才生效。误以为写个 var(--color, #000) 就能兜住所有异常,是线上样式突然消失的最常见原因。
var() 的第二个参数到底什么时候起作用?
它只响应两种状态:
-
--color在整个样式表(包括:root、任意选择器、内联style)中从未出现过声明 -
--color被显式设为unset(例如.btn { --color: unset; })
以下情况 都不会触发回退:
-
--color: ""(空字符串)→ 解析为无效值,但“已声明”,不走回退 -
--color: initial→ 按 CSS 继承规则处理,比如color变成inherit -
--color: bluue(拼错颜色名)→ 声明合法但值非法,浏览器静默失败,仍不触发回退
验证方式很简单:getComputedStyle(el).getPropertyValue('--color') 返回 "",不代表未定义,只说明没找到或值为空;返回 "bluue" 才说明声明了但解析失败。
calc() 里用 var() 必须带默认值,否则整条计算失效
像 width: calc(100% - var(--gap)) 这种写法,一旦 --gap 未定义或被设为 unset,整个 calc() 表达式会退化为 auto 或初始值,而不是“退到 100%”。必须写成:
width: calc(100% - var(--gap, 12px));
注意点:
- 默认值必须是合法的 CSS 值,不能是另一个
var()(如var(--gap, var(--base-gap))在旧 Safari 会静默失效) - 媒体查询中动态改变量时,旧环境可能还没加载新值,
var(--gap, 12px)能确保降级不崩 - 如果
--gap是通过 JS 动态设置的,别传空字符串:el.style.setProperty('--gap', gap || '12px'),否则var(--gap, 12px)仍取空,不回退
IE11 完全不认 var(),fallback 在那里根本不存在
IE11 解析器看到 color: var(--text, #333),整条声明直接跳过,连 #333 都不会读。真正有效的 fallback 只有两种:
- 手动写两行,兼容值在前:
color: #333; color: var(--text, #333); - 用 PostCSS 插件(如
postcss-custom-properties)且配置preserve: false,把var()编译掉,只留降级值
注意:
- PostCSS 替换要求变量必须定义在
:root,且值为静态常量(不能是calc()或嵌套var()) -
@supports (background: var(--x))在 IE11 会直接报语法错误,不能用来做降级判断 - 如果项目必须支持 IE11,建议加一个
no-cssvars类,在 JS 加载前就启用纯 CSS 回退方案
最易被忽略的一点:你写的 var(--x, #000) 看似是兜底,其实只是把“未定义”的判定权交给了浏览器——而这个判定逻辑,和你直觉中的“没赋值=没定义”完全不同。真要稳,就得控制变量声明本身:要么确保 :root 里有基础值,要么 JS 设置时主动用 unset 或删属性,而不是留个空字符串假装安全。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











