原生css变量与sass变量本质不同:css变量支持运行时动态修改与继承,sass变量仅在编译时生效;前者用于深色模式、状态动画等动态场景,后者适用于单位运算、颜色函数等静态逻辑。

原生CSS变量不是“取代”Sass变量,而是承担了Sass根本做不到的事——运行时动态控制。你没法用$color实现深色模式切换,也没法用$spacing驱动组件状态动画,因为$color在打包后就消失了。
JS能读写--color,但对$color完全无感
浏览器里真实存在--primary-color这个属性,document.documentElement.style.setProperty('--primary-color', '#121212')执行完,所有background-color: var(--primary-color)的元素立刻重绘;而$primary-color只是Sass编译器内部的一个文本占位符,输出后的CSS文件里搜不到它,setProperty('$primary-color', ...)会直接抛InvalidPropertyError。
常见错误现象:
- Vue组件中写
:style="{ '--bg': themeBg }",但themeBg实际来自Sass变量——绑定的是编译时的死值,状态变了颜色不动 - 想用
getComputedStyle(el).getPropertyValue('--text')取当前主题文字色,结果发现$text根本没有这个API
var(--x)必须套calc(),$x * 2直接算
CSS变量本质是字符串,浏览器不解析其数值含义。写width: var(--gap) * 2整条声明会被忽略;必须写成width: calc(var(--gap) * 2)。Sass变量则天然支持单位运算、颜色函数、条件分支。
PigX UI Pro 前端开发指南 - Vue 3 + TypeScript + Element Plus。当用户提到 PigX UI、PigX 前端、lgb-mgui 项目、Vue 3 企业级后台开发、Element Plus 后台开发时使用此技能。
实操要点:
-
calc()里单位要一致:如果--base-font-size设为16px,calc(320px / var(--base-font-size))才合法;设成16(纯数字)也行,但不能混用 - 颜色变浅不能写
lighten(--primary, 10%)——CSS里没这语法,只能提前算好存成--primary-light - Sass中
@mixin rem-width($px) { width: calc(#{$px} / var(--base-font-size) * 1rem); }是正确路径,把除法留在运行时
:root定义全局,选择器内重定义即局部生效
CSS变量作用域由层叠规则决定::root { --border-radius: 6px; }全局可用;.card { --border-radius: 12px; }只影响该元素及其后代,子元素自动继承,无需额外声明。Sass变量靠@import顺序和文件作用域控制,没有继承概念,跨文件易冲突。
容易踩的坑:
- 在Vue/React的
<style scoped></style>里写:root { --color: red }→ scoped会加属性选择器(如:root[data-v-xxx]),破坏:root匹配,变量不生效 - 组件库(如Ant Design)暴露
--el-color-primary供覆盖,使用者改值即可;Sass版本必须改源码+重编译 - Sass模拟局部变量得靠
@mixin button($padding: 12px),每次调用都复制样式代码,体积膨胀
真正难的是边界意识:别指望--size做@if判断或遍历生成类名,也别试图在Sass里解析var(--size)——它们活在不同时间维度。一个在构建阶段被抹平,一个在DOM挂载后才开始工作。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










