!default 是“首次赋值守门员”,仅在 Sass 首次解析变量名时生效;若 @import 已提前定义同名变量(如 Element Plus 的 $color-primary: #409eff),后续 !default 声明将被完全忽略,故必须置于所有 @import 之前。

!default 不是“覆盖开关”,而是“首次赋值守门员”——它只在 Sass 第一次见到某个变量名时起作用,一旦跳过,就再没机会。
为什么 $primary-color: #007bff !default; 必须写在所有 @import 之前
SCSS 变量赋值是单向、不可逆的。Bootstrap、Element Plus 等库的 _variables.scss 文件里大量使用 $color-primary: #409eff !default;,但这个 !default 只对“它自己第一次被解析到”有效。如果你把自定义变量写在 @import "bootstrap/scss/variables" 之后,Sass 已经在前一行把 $primary-color 绑定为 #409eff 了,你后写的 $primary-color: #007bff !default; 直接被忽略。
- 正确顺序只能是:
@import "bootstrap/scss/functions";→ 你的自定义块(含$primary: #007bff !default;)→@import "bootstrap/scss/variables"; - 漏掉
functions会导致$primary-rgb等派生变量仍用默认值,按钮背景变了但文字色还是黑的 - Vite 中若通过
css.preprocessorOptions.sass.additionalData注入变量,它比任何@import都早执行,极易提前“占坑”
为什么 @use + with 要求源文件必须显式声明 !default
@use 创建私有模块作用域,with 子句不是“强行改值”,而是“在导入时传参初始化”。如果源模块 vars.scss 里写的是 $spacing: 1rem;(没 !default),你在别处写 @use "vars" with ($spacing: 1.5rem);,Sass 会直接报错 This variable was not declared with !default。
- 想支持外部覆盖,源文件必须写
$spacing: 1rem !default; -
@forward "vars" with ($spacing: 1.5rem !default);是跨模块共享的替代方案,但要注意转发链中不能丢掉!default - 退回到
@import虽能绕过限制,但会污染全局命名空间,多个组件库混用时容易冲突
为什么 :root 里写 --color: $primary; 总是失效
SCSS 变量不能直接出现在 CSS 自定义属性的值位置。--color: $primary; 不会被编译成颜色值,而是原样输出字符串 --color: $primary;,浏览器无法识别。
立即学习“前端免费学习笔记(深入)”;
- 必须用插值语法:
--color: #{$primary}; - 计算函数也要包进
#{}:--bg-light: #{lighten($primary, 10%)}; -
!default对--xxx完全无效——CSS 变量的默认值得靠运行时语法:var(--color, #333) - 别写
$--color: #fff !default;,SCSS 不允许--开头的变量名,编译直接失败
最容易被忽略的一点:你看到的“主题没变”,大概率不是代码写错了,而是某处提前声明了同名变量——去 node_modules/ 里全局搜 $color-primary:,比反复检查自己写的 !default 更快定位问题。


















