回退值仅在变量完全未声明或值语法非法时生效;已声明为空字符串、unset、initial或拼写错误的值均不触发回退,且IE11不支持var()需手动fallback。

回退值不是“默认值”,它只在变量**完全未声明**或**值语法非法**时生效;已声明为空字符串、unset、initial或拼写错误的值(如bluue),都不会触发回退。
var() 的第二个参数到底什么时候生效
很多人以为写了 var(--color, #000) 就万事大吉,结果发现文字变透明了——那是因为 --color 已被声明为 "" 或 unset,浏览器认为“变量存在”,直接取该值,根本不会看逗号后面的 #000。
-
getComputedStyle(el).getPropertyValue('--color')返回""→ 表示已声明但为空,不触发回退 - 返回
null→ 才是真未定义,此时回退值才起作用 - 值为
inherit、initial、unset或非法颜色(如bluue)→ 仍属“已定义”,不走回退 - 媒体查询中覆盖变量时,别用
--color: ;清空,而应赋一个有效值(如--color: gray;)或删掉该行声明
多级回退必须嵌套 var(),但不能循环引用
想实现“组件变量 → 主题变量 → 字面量”的降级链,得靠 var(--a, var(--b, #000)) 这种写法。浏览器会先查 --a,未定义则查 --b,再未定义才用 #000。
- 嵌套建议最多两层:
var(--btn-bg, var(--primary, #007bff))安全;三层虽语法合法,但可读性和调试成本陡增 - 禁止循环:
var(--a, var(--b, var(--a, black)))在 Chrome 会报CSS Parser: cycle detected in variable reference,整条声明静默失效 - 回退值里的
var()是独立解析的,作用域不继承外部上下文——--b要在当前选择器作用域内有定义,否则直接走它的回退 - 最内层必须是字面量(如
#000、1rem),不能是另一个未定义变量或函数式表达式
旧浏览器(如 IE11)根本不认 var(),得手动 fallback
var(--x, #000) 对 IE11 毫无意义——它看到 var() 就整条 CSS 声明跳过,连逗号后的 #000 都不解析。
立即学习“前端免费学习笔记(深入)”;
- 正确写法是:先写静态值,紧跟着写
var()覆盖,且必须在同一规则块内color: #333;<br>color: var(--text-color, #333);
- 简写属性(如
background、border、font)必须拆成原子属性,每条单独加 fallback - 所有变量定义必须放在
:root,IE11 不支持局部作用域变量,也不支持从 class 上继承变量 - JS 动态设置变量后,CSS 不会自动重算回退值——
el.style.setProperty('--size', '')后,font-size: var(--size, 16px)仍取空字符串,不是16px
真正可靠的回退,靠的不是“写了 fallback 就安心”,而是确保变量要么不声明,要么声明为合法值;同时为旧环境预留静态兜底,且避免把回退逻辑堆在 JS 层或复杂嵌套里——越简单,越不容易断。


















