未定义的 css 变量才会触发 var() 回退值,若变量已声明但值为空、非法或作用域不覆盖,则不走回退,可能继承或取初始值;ie11 不支持 var() 需双写兼容;调试应优先查看 computed 面板。

未定义的 CSS 变量不会报错,var() 会尝试取你写的第二个参数(回退值),但这个行为有严格前提:变量必须是「完全未声明」,或被显式设为 initial/unset;若只是值非法(比如 --size: 12 缺单位)、空字符串(--bg: ;)或作用域没覆盖到,var() 不一定走回退,而是可能渲染为继承值或初始值。
var() 的回退值只在变量“真未定义”时生效
很多人以为写了 color: var(--text-color, #333) 就万事大吉,结果发现样式没变、颜色是透明或继承来的黑色。这是因为:
-
--text-color其实已在某处声明了,比如.theme { --text-color: ; }—— 空字符串是“已声明但无效”,var()不触发回退,整条声明被丢弃,属性按 CSS cascade 规则回退到父级 color - 变量声明在
.card内部,但你在.btn里用var(--text-color),又没继承链,那就真未定义 → 此时回退才生效 - 用
getComputedStyle(el).getPropertyValue('--text-color')拿到空字符串"",不代表未定义,只代表没找到或值为空;得结合 DevTools 的 Computed 面板看最终计算值是否为inherit或initial
嵌套 var() 回退链容易静默失效
你可以写 border-color: var(--a, var(--b, red)),但得防住两个坑:
- 循环引用:如果
--a: var(--b)且--b: var(--a),Chrome 和 Firefox 会静默失败,最终取属性的初始值(比如color变成inherit),不报错也不警告 - 中间变量缺失:
var(--a, var(--b, red))中若--b也未定义,那没问题;但如果--b被声明为unset或空字符串,它自己不会触发自己的回退,整个链就断了 - 调试建议:打开 DevTools → Computed → 找对应属性,点开小箭头看 “Computed value” 是什么,比查源码快得多
IE11 和旧浏览器根本不认 var() 语法
var(--x, #000) 在 IE11 里不是“走默认值”,而是整行 CSS 被跳过,属性回归浏览器默认(比如 background 变透明)。要兼容,必须用“静态值 + var() 覆盖”的双写法:
- 同一选择器内,先写无条件静态值:
background-color: #fff; - 紧接着写带回退的
var():background-color: var(--card-bg, #fff); - 简写属性如
background、border、font必须拆成原子属性再加 fallback,否则 IE 直接丢弃整条 - fallback 值必须带单位:如果
--gap是12px,回退就得写12px,不能只写12
服务端渲染和 JS 动态设置时的陷阱
SSR 场景下,HTML 输出时 JS 还没执行,:root 里漏一个变量就是真未定义;而 JS 设置时,el.style.setProperty('--size', '') 会让后续 var(--size, 16px) 走默认值——因为空字符串被 var() 视为无效值。
真正难 debug 的地方往往不在语法本身,而在「你以为它未定义,其实它被某个祖先元素悄悄声明了但值为空」,或者「你检查了 :root 却忘了组件内部作用域覆盖了变量但没传全」。动手前,先看 Computed 面板里的最终值,比猜快十倍。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











