scss变量不生效的根本原因是混淆了sass编译期变量与css运行时变量:$color-primary需用#{$color-primary}插值才能赋给--color-primary,否则原样输出为无效css;同时须排查node_modules中同名变量覆盖及作用域问题。

根本原因不是变量“失效”,而是你把 Sass 编译期变量和 CSS 运行时变量混用了——$color-primary 在 Sass 里是值,--color-primary 在浏览器里才是变量;不插值、不加载顺序对、不作用域对,它就永远只是个字符串。
SCSS变量不能直接赋给CSS自定义属性
写 --color-primary: $color-primary; 看似合理,但 Sass 编译器不会自动展开变量。它会原样输出为 --color-primary: $color-primary;,浏览器直接当无效声明丢弃。
- 必须用插值语法:
--color-primary: #{$color-primary}; - 带函数计算也得包住:
--color-light: #{lighten($color-primary, 10%)}; - 如果
$color-primary本身来自!default,还要确认它没被node_modules里的同名变量提前覆盖(全局搜$color-primary:)
DevTools显示变量已定义 ≠ 实际生效
你在 :root 样式面板看到 --color-primary: #2196F3,不代表组件能读到它。重点看目标元素的 Computed 面板里 background-color 的最终值来源:
- 如果是
rgb(33, 150, 243)或十六进制,说明规则里压根没引用var(--color-primary),而是硬编码了颜色 - 如果是
initial或继承值,说明变量作用域断了——比如在 Shadow DOM 里没显式::host { --color-primary: inherit; } - 如果
Styles面板里该变量灰掉或带删除线,说明定义本身非法(拼错、缺单位、嵌套var())
Element Plus 升级后变量“失效”的典型链路
这不是你的 SCSS 写错了,而是构建链路残留导致 CSS 变量被绕过:
- 全局搜索
import 'element-plus/dist/index.css',包括main.ts、vite.config.ts、插件配置——只要有一处,它就把--el-color-primary直接编译成#409eff,浏览器不再查:root - 用了
unplugin-element-plus?必须显式设useSource: true,否则默认注入dist样式,覆盖你的 SCSS 编译结果 - 按需引入时,
unplugin-vue-components和unplugin-auto-import的ElementPlusResolver都要单独配importStyle: 'sass',漏一个就回退到dist蓝色
为什么 var(--size) 不能在 Sass 函数里用
var() 是浏览器运行时机制,Sass 编译器启动时 DOM 还不存在,document.documentElement 是 undefined,所以 @function pxToRem($px) { $base: var(--base-font-size); } 必然报错。
- 想动态响应 JS 设置的
--base-font-size?用calc()把计算留在 CSS 层:width: calc(#{$px} / var(--base-font-size) * 1rem); - Sass 里只能用
$base-font-size: 16px这类编译期常量做静态计算 - 别试图在 Sass 里
@if $base > 20px判断 CSS 变量值——它根本不可见
真正容易被忽略的是:SCSS 变量是否被注入、是否插值、是否被第三方库覆盖,这三件事都发生在构建阶段;而 CSS 自定义属性是否生效,取决于 DOM 结构、继承链、样式优先级和浏览器解析顺序——它们分属两个完全不同的生命周期,强行混用只会静默失败。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











