scss变量无法运行时修改,仅在编译阶段生效;真正支持运行时修改的是css自定义属性(--xxx),需通过scss生成var(--xxx)语句并由js控制其值。

SCSS变量本身不支持运行时修改——它在编译阶段就被替换成固定值,最终CSS里根本不存在$变量。真正能运行时改的,只有CSS自定义属性(--xxx)。所谓“让SCSS变量支持运行时修改”,本质是用SCSS生成依赖var(--xxx)的样式,并把--xxx的值交给JavaScript控制。
为什么直接在:root里写$color会报错
很多人尝试这样写:
:root {
$primary-color: #409eff;
}
然后在类里用color: $primary-color——这必然失败。因为$primary-color是Sass编译器识别的语法,浏览器完全不认识;而:root是CSS运行时选择器,两者不在同一阶段。
-
$变量只在.scss文件里有效,编译后就消失了 -
--xxx是标准CSS属性,存在于DOM中,可被getComputedStyle()读取、style.setProperty()修改 - 想“动态”,必须桥接:SCSS负责生成
color: var(--primary-color)这类语句,而不是硬编码颜色值
在SCSS里安全使用var(--xxx)的写法
不能直接把var(--color)赋给SCSS变量再用,比如$c: var(--color); color: $c——Sass会把它当字符串处理,最终输出color: var(--color)没错,但若你后续想在calc()或mix()里复用这个值,就会出错。
- 正确做法:所有需要运行时变化的值,统一用
var(--xxx)直接写在CSS声明里 - 例如:
background-color: var(--bg-color, #fff),其中#fff是降级备用值 - 如果要用在
calc()中,确保--xxx本身是数值型单位(如--spacing: 8px),然后写margin: calc(var(--spacing) * 2) - 避免在
@if或lighten()等Sass函数里传入var(--xxx)——它们需要编译期确定的值,无法处理运行时变量
UniApp/Vue项目中落地的关键三步
以UniApp为例,目标是点击按钮切换圆角强度,且不刷新页面:
- 第一步:在
:root里定义--shape-radius: 6px,并在全局SCSS中用border-radius: var(--shape-radius)替换所有border-radius: $radius - 第二步:在Vue组件的
setup中,用document.documentElement.style.setProperty('--shape-radius', '12px')触发切换 - 第三步:注意兼容性——
var()在iOS Safari 13.4+、Chrome 49+、Firefox 31+完全支持;旧版需加border-radius: 12px作为回退声明(放在var()前面)
容易忽略的性能与维护陷阱
看似简单,但实际项目里最常栽在这几个点上:
- 把所有设计令牌(颜色、圆角、阴影)都塞进
:root,导致根节点CSSOM过大,影响首屏渲染——应按需注入,比如暗色模式只在.dark类下定义--bg-color - 用JavaScript频繁调用
setProperty()修改多个变量,引发多次重排——建议批量合并,或用CSSStyleSheet.replace()替换整块主题CSS - SCSS里混用
$spacing-sm和var(--spacing-sm),造成维护混乱——明确分工:SCSS变量只用于编译期计算(如$btn-height: $spacing-lg * 2),运行时值一律走var()
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











