var(--x, #000) 的回退值仅在--x未声明或被设为initial/unset时生效,其余如空声明、非法值、继承中断等均不触发回退;简写属性中使用易致整条声明失效,应拆分为子属性;嵌套var()需防循环引用。

写了 var(--x, #000) 却没生效,大概率不是语法错,而是你误把“回退值”当成了“万能兜底”——它只在特定条件下触发,其他情况会静默失效。
为什么 var(--x, #000) 的默认值不触发
这个回退值只在两种情况下起作用:一是 --x 根本没在任何作用域(:root、父元素等)中声明;二是它被显式设为 initial 或 unset。其余所有“看似未定义”的场景,它都不管:
-
:root { --x: ; }—— 空字符串是“已声明但无效”,var()丢弃该值,但**不走回退**,整个声明失效 -
:root { --x: 123 }—— 值非法(缺单位),浏览器尝试解析失败,部分引擎可能 fallback,但不保证,且不统一 -
.parent { --x: red; } .child { color: var(--x, #000); },但.child没继承到(比如被all: unset干扰)——此时计算值可能是inherit或初始值,var()不介入
怎么确认是不是真“未定义”
别信 getComputedStyle(el).getPropertyValue('--x') 返回空字符串就代表未定义——它对“未声明”和“声明为空”都返回 ""。真正可靠的方式是:
- 打开 DevTools → Elements → 选中目标元素 → Computed 面板 → 搜索
--x:如果完全不出现,说明变量没声明 - 在 Styles 面板里点开含
var(--x, #000)的那条规则,看右侧是否标红或显示invalid - 执行
getComputedStyle(document.documentElement),展开属性列表,手动找--x是否在其中
简写属性里用 var() 回退值极容易失效
像 border: 1px solid var(--border-color, #ccc) 这种写法,一旦 --border-color 拼错或未声明,整个 border 声明会退化为 border: 1px solid;,最终渲染出透明边框,而不是你期待的 #ccc。
原因在于 CSS 简写属性对子属性缺失极其敏感,且不会单独 fallback 某个值。更稳妥的做法是拆开:
border-width: 1px; border-style: solid; border-color: var(--border-color, #ccc);
这样即使 --border-color 失效,border-color 仍会走回退,其他两个子属性也不受影响。
嵌套 var() 默认值时防循环引用
写 var(--primary, var(--fallback, #000)) 是合法的,但若 --fallback 又反过来引用 --primary,就会形成死循环。Chrome 和 Firefox 会静默放弃解析,最终取属性的初始值(比如 color: inherit),而不是报错或 fallback 到 #000。
调试时直接看 Computed 面板里的最终计算值最有效——如果它既不是你设的变量值,也不是你写的回退色,而是 inherit 或空白,大概率是链式降级某一级断了,或者循环了。
真正难定位的,永远是那个拼写只差一个字母、作用域漏了一层、或 SSR 时 :root 没提前注入变量的情况——它们都不报错,只让样式悄悄消失。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











