应优先使用css自定义属性(--primary-color)而非sass变量($primary-color),因其支持运行时主题切换、组件级样式覆盖和js动态控制,而sass变量仅限编译期计算且无法在dom中读写或响应式更新。

大型项目里该用 --primary-color,别用 $primary-color——除非你明确需要编译期计算或条件分支。运行时主题切换、组件级样式覆盖、JS驱动的动画参数调整,这些事 $ 根本做不到。
运行时修改 --color 立刻重绘,改 $color 是对空气说话
浏览器只认 --xxx 这种真实存在的 CSS 属性,$xxx 在编译完就彻底消失,DOM 里查不到、JS 读不到、也设不了。
-
document.documentElement.style.setProperty('--bg', '#121212')执行后,所有var(--bg)立刻响应,过渡动画照常触发 -
document.documentElement.style.setProperty('$bg', '#121212')直接报错:CSS property name is invalid - Vue/React 中写
:style="{ '--bg': themeBg }"却用 Sass 变量定义themeBg→ 值永远是编译时快照,状态变了颜色不动
--spacing 支持局部覆盖,$spacing 一改全炸
CSS 变量按层叠规则生效,天然适配组件化;Sass 变量靠文件导入顺序和命名空间硬控,稍不注意就全局污染。
-
.card { --spacing: 24px; }→ 卡片及其子元素自动继承新值,不影响其他模块 -
$spacing: 24px写在_vars.scss里,被 10 个组件@import后,改一处可能让按钮、表单、弹窗全乱套 - 想模拟局部?Sass 得靠
@mixin button($padding: 12px),每次调用都复制整段 CSS,体积膨胀且无法复用已计算值
calc(var(--gap) * 2) 可行,var(--gap) * 2 直接失效
CSS 变量本质是字符串,所有数学运算必须包在 calc() 里;Sass 变量是预处理器层面的“真变量”,但代价是失去运行时能力。
- 宽度动态缩放:
width: calc(var(--base-size) * 1.5);✅;width: var(--base-size) * 1.5;❌(整条声明被浏览器忽略) - 颜色变浅:
lighten($primary, 10%)✅ Sass 编译即出新色值;CSS 里没等价语法,只能提前算好存成--primary-light - 条件逻辑:
@if $theme == 'dark'✅ 编译时分支;CSS 变量无法做@if,深色模式得靠 JS 或@media (prefers-color-scheme: dark)配合
构建流程与兼容性取舍很现实
纯 CSS 变量零构建、零转译、现代浏览器全支持;Sass 必须走编译流程,多主题还得打包多份 CSS,带来 FOUC、缓存断裂、transition 失效等问题。
- IE 不支持
--var?那就加降级:color: #333; color: var(--text-color);,现代浏览器自动覆盖 - Sass 多主题方案要输出
light.css和dark.css,再用 JS 切换<link>→ 加载延迟、无渐变、样式表重解析 - 组件库(如 Ant Design)暴露
--el-color-primary给用户覆盖,Sass 版本则必须改源码 + 重编译,根本没法嵌入低代码平台或主题市场
真正难的是把“哪些值该提成 CSS 变量”想清楚——比如 --border-radius-sm 这种固定尺寸可以,但 lighten($primary, 5%) 这类依赖运行时上下文的计算,就得提前算好存成多个变量,或者干脆交给 JS 处理。混用或误判,比不用更糟。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











