CSS自定义属性(--color)可被JS实时修改并触发重绘,而Sass变量($color)仅在编译期存在,运行时无效;数学运算需用calc()包裹var(),Sass变量则支持直接运算;:root在scoped中失效,须放全局样式。

根本不是一回事——--color能被 JavaScript 实时改、浏览器立刻重绘;$color编译完就没了,JS 对它做任何事都等于对空气说话。
为什么 document.documentElement.style.setProperty('--bg', '#121212') 有效,但 setProperty('$bg', ...) 报错
--bg 是浏览器原生支持的 CSS 自定义属性,真实存在于 CSSOM 中,getComputedStyle() 能读、setProperty() 能写、改完下一帧就重绘。$bg 只是 Sass 编译器内部的文本占位符,输出的 CSS 文件里根本不存在这个符号,浏览器连识别都不会识别,自然报 InvalidPropertyError。
常见错误现象:
- Vue 组件里写 :style="{ '--theme': themeBg }",但主题色底层用的是 $theme-bg → 值永远卡在编译那一刻
- 控制台执行 document.documentElement.style.setProperty('$primary-color', 'red') 直接抛错
- getComputedStyle(document.body).getPropertyValue('--text') 返回值,getPropertyValue('$text') 永远是空字符串
var(--gap) * 2 报错,但 calc(var(--gap) * 2) 可行
--gap 存的只是字符串,浏览器不解析其数值含义;所有数学运算必须显式包裹在 calc() 里。而 $gap 是 Sass 预处理器层面的“真变量”,支持类型识别和直接运算。
PigX UI Pro 前端开发指南 - Vue 3 + TypeScript + Element Plus。当用户提到 PigX UI、PigX 前端、lgb-mgui 项目、Vue 3 企业级后台开发、Element Plus 后台开发时使用此技能。
-
width: calc(var(--spacing) * 2);✅ 合法 -
width: var(--spacing) * 2;❌ 整条声明被忽略 -
$size: 16px * 1.5;✅ Sass 编译时算出24px -
lighten($c, 10%)✅ 编译生成新颜色;CSS 里没等价语法,只能提前算好存成--primary-light
:root { --x: y } 在
:root 是全局选择器,scoped 会自动添加属性选择器(如 [data-v-xxx]),导致 :root[data-v-xxx] 根本不匹配,变量无法注入文档根节点。
立即学习“前端免费学习笔记(深入)”;
正确做法:
- 全局变量统一放在非 scoped 的样式块中,比如项目根目录的 main.css 或 index.html 的 <style>
- JS 修改必须走 document.documentElement.style.setProperty(),别用 document.body —— 否则后代元素可能拿不到继承值
- 局部覆盖直接在选择器内重定义:.card { --shadow: 0 4px 12px rgba(0,0,0,0.15); },子元素自动继承
真正容易被忽略的是混合场景:比如在 Sass 文件里用 @include button-theme($color) 生成一堆硬编码样式,同时又试图用 JS 改 --button-bg —— 两者互不感知,改了也白改。分工得清楚:$color 负责编译期逻辑和计算,--color 负责运行时状态响应。

















