css变量是运行时动态样式的核心,支持js读写、主题切换和组件状态驱动;sass变量仅编译时生效,无法实现动态控制,二者应混合使用而非替代。

因为 Sass 变量根本做不到运行时动态控制,而这是现代前端必须解决的问题——主题切换、用户偏好、组件状态驱动样式,全依赖 CSS 变量。
JS 能读写 --color,但对 $color 完全无感
浏览器里不存在 $color 这个东西。Sass 编译完,所有 $ 都被替换成硬编码值(比如 #4285f4),输出的 CSS 文件里搜不到半个 $。而 --color 是真实存在的 CSS 属性,JS 可以直接操作:
-
document.documentElement.style.setProperty('--bg', '#121212')→ 深色模式毫秒生效 -
getComputedStyle(document.body).getPropertyValue('--text')→ 拿到当前计算值 -
element.style.setProperty('--opacity', '0.8')→ 动画中实时调节透明度
常见错误:Vue 组件里写 :style="{ '--bg': themeBg }",但 themeBg 来自 Sass 变量 → 实际绑定的是编译时的死值,状态变了颜色也不变。
var(--gap) 必须套 calc(),$gap * 2 直接算
CSS 变量本质是字符串,不能裸奔参与运算;Sass 变量是预处理器层面的“真变量”,支持单位计算、颜色函数、条件分支。
- ✅ 正确:
width: calc(var(--spacing) * 2); - ❌ 错误:
width: var(--spacing) * 2;→ 整条声明被浏览器忽略 - ✅ Sass 里:
$size: 16px * 1.5;→ 输出24px - ❌ CSS 里没有
lighten(--primary, 10%),只能提前算好存成--primary-light
所以别指望用 CSS 变量做复杂逻辑——它不是替代 Sass 的,而是补足它做不到的事。
PigX UI Pro 前端开发指南 - Vue 3 + TypeScript + Element Plus。当用户提到 PigX UI、PigX 前端、lgb-mgui 项目、Vue 3 企业级后台开发、Element Plus 后台开发时使用此技能。
:root 定义全局,选择器内重定义即局部生效
CSS 变量作用域由层叠规则决定,天然适配组件化开发;Sass 变量靠文件导入和嵌套控制,容易失控。
-
:root { --border-radius: 6px; }→ 全局默认 -
.card { --border-radius: 12px; }→ 仅影响该元素及其后代 - Sass 中想模拟局部变量?只能靠
@mixin button($padding: 12px)→ 每次调用都复制整段样式,体积膨胀 - 组件库(如 Ant Design)暴露
--el-color-primary,使用者直接覆盖;Sass 版本必须改源码 + 重编译
Vue/React 中若在 <style scoped></style> 里写 :root { --color: red } → 不生效(scoped 会加属性选择器,破坏 :root 匹配)。
Vite 开发时改 --x 立刻重绘,改 $x 触发全量重编译
原生 CSS 变量无需构建步骤,修改后只触发 CSSOM 更新;Sass 变量每次改动都要走完整编译链路。
- 改
--spacing-sm→ DevTools “Styles” 面板实时看到效果,不刷新页面 - 改
$spacing-sm→ 所有引用它的.scss文件重编译,Vite HMR 常常整页刷新 - 大量
var(--x)会导致 gzip 后体积略大(重复字符串未合并),但换来的是 JS 控制力和调试效率 - 真正轻量的做法是混合使用:主题色、断点开关用 CSS 变量;间距比例、循环生成栅格仍走 Sass
最易被忽略的一点:@media (min-width: var(--sm)) 这种写法目前仅 Chrome 119+、Firefox 支持,别在旧项目里盲目套用。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










