SCSS变量($color)仅在编译期存在并替换为静态值,CSS变量(--color)则在运行时由浏览器解析并支持JS动态修改;二者生命周期完全分离,必须用#{$var}插值才能将SCSS值注入CSS变量声明,否则声明会被静默丢弃。

SCSS变量和CSS变量根本不在同一个时间点工作
编译时就没了的 $color 和运行时才起作用的 --color,名字像、写法像,但生命周期完全错开。你改了 $color,只影响下一次构建;你改了 --color,页面立刻变色——这不是 bug,是设计如此。
常见错误现象:
- 在
:root里写--primary: $primary;,结果 DevTools 里压根看不到这条声明 - 以为给
:root设了--bg,再在 SCSS 里写$bg: var(--bg);就能读取——实际报错或编译出无效值 - 调试时发现“变量没生效”,其实是它根本没被生成,而不是浏览器不认
必须用 #{$var} 才能把 SCSS 值塞进 CSS 变量声明
#{} 是 Sass 唯一能将编译期变量“注入”到原生 CSS 语法中的方式。它不做任何运行时逻辑,只是字符串拼接。
正确写法示例:
立即学习“前端免费学习笔记(深入)”;
$primary: #3b82f6;
:root {
--primary: #{$primary};
--spacing-sm: #{rem(4)};
}容易踩的坑:
-
--primary: $primary;→ 静默丢弃整条声明(Sass 不认识这种写法) -
--primary: # { $primary };→ 多了个空格,插值失效,输出字面量# $primary - 在
calc()外套 Sass 函数,比如width: round($w / 2);→ Sass 会尝试算除法,但单位混用直接报错
别指望它们自动同步或互相读取
$x: var(--y); 无效,--z: darken($c, 10%); 也无效。SCSS 编译器不会解析 CSS 运行时函数,浏览器也不会执行 Sass 函数。
真正需要联动时,只有两种可靠路径:
- 构建时生成:用
@each循环把 SCSS 变量批量转成多套 CSS 变量,比如按主题生成--primary-light、--primary-dark - 运行时控制:JS 操作
document.documentElement.style.setProperty('--primary', '#...'),或通过 class 切换触发.theme-dark { --primary: #000; }
想靠一个变量名同时服务编译期复用和运行时响应,本质上是在要求两个不同系统做同一件事——它们做不到,也不该这么做。
插值出来的值是静态的,不是活的 CSS 变量
写 color: #{$primary}; 和写 color: var(--primary); 看似效果一样,但前者是构建后写死的 color: #3b82f6;,后者才是真正的动态引用。
这意味着:
- 如果你后续用 JS 改了
--primary,所有var(--primary)会响应,但所有#{$primary}输出的值不会变 - 插值适合用于生成基础主题骨架(如
:root中的初始值),不适合用于组件内部需频繁响应的场景 - 一旦用了插值,就等于放弃了 CSS 变量最核心的能力:运行时可变性
真正难处理的,从来不是怎么写对,而是想清楚:这里到底需要编译期确定,还是运行时可调?选错时机,后面全是补丁。


















