SCSS变量在构建阶段即被替换为固定值,无法运行时修改;CSS变量(如--primary-color)是浏览器原生支持的运行时属性,可通过JS动态读写并实时重绘。
Sass 变量在构建阶段就被替换成具体颜色值,比如 $primary-color: #409eff 编译后直接变成 color: #409eff;。浏览器加载的 CSS 文件里没有任何 $ 符号,document.documentElement.style.setProperty('$primary-color', 'red') 会报错,getComputedStyle() 也查不到它——它压根没进运行时环境。
@if 是编译期指令,只在你执行 sass 命令或启动 Vite/Webpack 时运行一次。此时 document 还不存在,localStorage、prefers-color-scheme、按钮点击事件全不可见。常见错误包括:
$theme: 'dark' 后在组件里改 JS 状态,但样式毫无变化vue-cli-plugin-style-resources-loader 注入变量,误以为能动态更新动态主题必须靠 --primary-color 这类 CSS 变量 + JS 控制,例如:
document.documentElement.style.setProperty('--primary-color', '#1e88e5');
所有样式都得基于 var(--primary-color) 引用,不能混用 Sass 变量值。否则会出现“JS 改了变量,页面颜色卡在编译那一刻”的典型现象。Sass 的作用仅限于安全生成这些 var() 语句,比如用 @each 遍历 $theme-colors map 输出完整的 :root 规则。
如果你需要为不同客户输出独立 CSS 文件(如 light.css 和 dark.css),可以用 CLI 分别传参编译:sass --define=theme=light main.scss:light.css。但这和用户点按钮实时切换无关——后者必须依赖 data-theme class 或 CSS 变量 + JS 更新。最容易被忽略的是:Sass 编译结果里没有 @if、没有 $、也没有“条件”,只有静态 CSS;一旦忘了在源码里注释清楚哪个 map 键对应哪套 UI,半年后你自己都看不出为什么某个卡片突然变灰了。