前端开发中 SCSS 变量与 CSS 变量的区别与实践选择,—— 两种变量别混为一谈
一、SCSS 变量与 CSS 变量的本质区别
在 Vue 或任意前端项目中,我们经常同时使用 SCSS 与 CSS 变量。
它们的语法相似,但工作原理完全不同。
对比维度 | SCSS 变量 | CSS 变量(自定义属性) |
---|---|---|
定义方式 | $primary-color: #409EFF; | --primary-color: #409EFF; |
使用方式 | color: $primary-color; | color: var(--primary-color); |
解析阶段 | 编译时(构建时由 Sass 替换) | 运行时(由浏览器解析,可动态修改) |
作用范围 | Sass 文件内部或导入链内 | CSS 层级继承(可以定义在 :root 、类、标签中) |
是否动态 | ❌ 静态,构建后无法再改 | ✅ 可通过 JS 或类名动态切换 |
浏览器支持 | 所有浏览器(最终是普通 CSS) | 现代浏览器(IE 不支持) |
二、特别注意:SCSS 变量写在 :root
中是无效的!
很多人初学时,会这样写:
:root {$primary-color: #409eff;
}
然后希望这样用:
.button {color: $primary-color;
}
❌ 结果:编译报错!或者变量根本不生效。
原因解释
SCSS 变量在编译阶段就会被处理掉,它不存在于最终生成的 CSS 文件中。
Sass 预处理器在编译时根本不会识别
:root
内的$变量
,因为$变量
并不是 CSS 属性。
换句话说:
$变量
是编译阶段的指令,而:root
是运行时的选择器。
二者不在同一个阶段生效。
正确写法应该是:
// variables.scss
$primary-color: #409eff;.button {color: $primary-color;
}
或者如果你想让 CSS 在运行时也能读取到一个变量,就要用 CSS 自定义属性:
:root {--primary-color: #409eff;
}.button {color: var(--primary-color);
}
三、在 Vue 项目中的使用注意事项
3.1 SCSS 变量:编译期常量,写在全局变量文件中即可
// src/styles/variables.scss
$primary: #409eff;
$font-size-base: 14px;
然后在 vite.config.ts
中全局注入:
css: {preprocessorOptions: {scss: {additionalData: `@import "@/styles/variables.scss";`}}
}
不需要 :root
,也不应该放在 :root
中。
因为 $变量
只在 Sass 编译期存在,写在任何选择器里都不会影响结果。
3.2 CSS 变量:运行时变量,必须放在 :root
或具体选择器中
:root {--color-primary: #409EFF;
}.dark {--color-primary: #66b1ff;
}.button {color: var(--color-primary);
}
SS 变量存在于运行时,可以通过 JavaScript 动态修改:
document.documentElement.style.setProperty('--color-primary', '#ff0000');
四、如何结合使用两种变量?
实际开发中,两种变量往往结合使用,取长补短:
// 使用 SCSS 计算和生成 CSS 变量
$theme-light: #fff;
$theme-dark: #000;:root {--theme-light: #{$theme-light};--theme-dark: #{$theme-dark};
}
这样:
SCSS 负责计算和组织变量;
CSS 变量负责在运行时控制主题。
五、实践中的选型建议
场景 | 推荐使用 |
---|---|
固定样式(颜色、间距、字号等) | ✅ SCSS 变量 |
动态主题、暗黑模式 | ✅ CSS 变量 |
响应式计算、尺寸比例 | ✅ SCSS 变量 |
JS 需动态控制颜色 | ✅ CSS 变量 |
组件库(既要暴露主题接口,又要可计算) | 混合:SCSS 生成 CSS 变量 |
六、总结
SCSS 变量是编译期的计算逻辑,不需要、也不能放在 :root
中。
CSS 变量是运行期的样式变量,必须定义在 :root
或具体元素内。
二者一个属于“开发阶段”,一个属于“浏览器阶段”,
搞清楚它们的“时空位置”,就不会再混淆。