css变量不支持定义时自带默认值,但可通过var(--a, var(--b, #000))实现多级回退;第二个参数必须是合法css值,--b仅为属性名非法,而var(--b, #000)是可求值表达式;空字符串、initial等已声明值不触发回退,且嵌套需避免循环引用。

var()嵌套回退链必须写成合法CSS值,不能直接传变量名
很多人想写 var(--a, --b) 让它 fallback 到另一个变量,这是非法的。第二个参数必须是**可求值的 CSS 值**,而 --b 只是一个属性名,不是值。真正合法的是 var(--a, var(--b, #fff))——因为 var(--b, #fff) 本身就是一个完整、浏览器能解析的表达式。
-
✅ 正确:color: var(--text-primary, var(--text-base, #333)); -
❌ 错误:color: var(--text-primary, --text-base);(整条声明被忽略) -
⚠️ 注意:嵌套层级没有硬性限制,但超过两层(如var(--a, var(--b, var(--c, #000))))会让调试变困难,且无法检测循环引用(比如--a: var(--b, red); --b: var(--a, blue))
空字符串、initial、inherit 不触发任何回退
这是最常踩的坑:只要变量被声明过,哪怕值是空、initial 或语法错误(如 --color: bluue;),var() 就不会跳到回退值。浏览器会尝试解析那个非法值,失败后可能降级为 inherit 或继承值,而不是启用 fallback。
-
:root { --bg: ""; }→background: var(--bg, #fff)渲染为透明(""被当作有效值) -
:root { --size: initial; }→font-size: var(--size, 16px)实际取initial(通常是浏览器默认字号) - 验证方式:
getComputedStyle(document.documentElement).getPropertyValue('--bg')返回""就说明已定义,回退失效
多级回退的变量查找作用域是独立的
var(--a, var(--b, #000)) 中的 --b 是在**当前选择器作用域内查找**,不是向上搜索父级或 :root。如果当前作用域没定义 --b,才会触发它的回退值。
-
.card { --a: red; background: var(--a, var(--b, #fff)); }→ 因为--b未定义,最终用#fff -
.card { --a: red; --b: green; background: var(--a, var(--b, #fff)); }→ 用green,哪怕:root里有--b: blue - 想复用全局 fallback?得把
--fallback-bg提到:root,或用 JS 统一设置
SCSS 中不能自动注入回退,必须显式插值
SCSS 不解析 var(),也不会帮你补 fallback。你写的 color: var(--text) 就原样输出,运行时才由浏览器决定是否回退。所以“优雅处理”靠的是结构设计,不是预处理器魔法。
-
✅ 安全写法:color: var(--text, #{$fallback-text});($fallback-text是 SCSS 变量) -
❌ 危险写法:color: var(--text, calc(var(--base) * 1.2));(IE 不支持,现代浏览器也不允许第二参数含未解析var()) - 别在第二参数里写复杂表达式,比如
#{map-get($colors, 'text')},容易出错且不可读
回退链越长,越难定位哪一级变量漏定义或被意外覆盖;真正健壮的方案不是堆砌多层 var(),而是控制变量声明的粒度和作用域——比如把主题色统一挂到 :root,组件只负责覆写,不自行定义 fallback 链。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











