scss变量$color-primary是编译期静态值,css自定义属性--color-primary是运行时动态值,二者必须分离管理;$变量用于构建逻辑,--变量用于js动态切换;需通过additionaldata注入、@use导入,并在:root中用#{$var}双向同步。

SCSS 本身没有“全局 CSS 变量”这个概念——$color-primary 是编译期静态变量,--color-primary 才是运行时的 CSS 自定义属性。两者必须分开管理、明确分工,混用会导致主题失效、调试困难、换肤失败。
区分 $variables 和 --custom-properties 的职责
这是最容易出错的第一步:把 SCSS 变量当 CSS 变量用,或反过来。
-
$color-primary用于构建时确定样式逻辑(比如@if $theme == 'dark')、生成固定类名、控制 mixin 行为,编译后不残留 -
--color-primary必须定义在:root下,通过 JS 动态切换(如document.documentElement.style.setProperty('--color-primary', '#2c5e1a')),支持无障碍模式切换、用户偏好响应 - 别在 SCSS 中写
color: var(--color-primary, $color-primary)—— 这看似兜底,实则让$color-primary失去语义:它本该是设计系统的源值,不该被降级为 fallback
SCSS 全局变量必须靠 additionalData 注入,而非 @import
手动在每个 .scss 文件顶部写 @import "@/styles/_variables.scss" 不仅重复,还会因导入顺序错乱导致 Undefined variable 错误。
- Vite / Vue CLI 5+ 唯一可靠方式是配置
css.preprocessorOptions.scss.additionalData - 必须用
@use "@/styles/_variables.scss" as *;,不是@import;as *才能把变量注入当前作用域 - 路径必须带
@/别名,且vite.config.js中已正确定义resolve.alias,否则解析失败 -
_variables.scss文件里只放变量、@function、@mixin,禁止任何选择器或@import其他样式文件
:root 中的 CSS 变量要集中声明,且与 SCSS 变量双向对齐
你不能只靠 CSS 变量实现主题,也不能只靠 SCSS 变量生成主题——它们得“对得上”。
- 在
src/styles/variables.css(或.scss)中统一写::root { --color-primary: #{$color-primary}; --color-text: #{$color-text}; --border-radius: #{$border-radius-base}; } - 这样既复用了 SCSS 变量的语义和层级,又输出了运行时可变的 CSS 属性
- 避免在
:root里硬编码色值,否则 SCSS 主题覆盖逻辑(如_theme-dark.scss)就断掉了 - 若需 JS 动态改主题,只操作
--color-primary等 CSS 变量;SCSS 变量仍保持构建时静态,不参与 runtime
复杂点在于变量层级和团队协作约束
真正卡住项目的从来不是技术配置,而是没人遵守「变量只在 _variables.scss 定义」「所有主题覆盖必须走 !default + 顺序导入」「CSS 变量只从 SCSS 源值生成」这三条铁律。一旦有人在组件里直接写 $color-primary: red !global 或在 :root 里手写 --color-primary: #ff0000,整套体系就不可维护了。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











