应使用#{ $color-primary }插值导出为CSS变量,因Sass变量编译后消失,直接写$color-primary会导致无效CSS;需确保变量已定义、类型合法,并优先用@use管理作用域。

直接结论:用 Sass 变量定义源值,用 :root + #{} 插值导出为 CSS 变量,二者职责分离——Sass 管编译期逻辑,CSS 变量管运行时动态性。
为什么不能直接在 :root 里写 $color-primary
因为 Sass 变量在编译后就消失了,:root { --color: $color-primary } 会原样输出到 CSS 中,浏览器不认识 $color-primary 这个语法,最终变成无效声明。必须用插值:--color-primary: #{ $color-primary };。
常见错误现象:
-
Invalid CSS after "--color:": expected expression—— 忘了插值,写了变量名而非值 -
Invalid null value for `#{}`—— 插值的变量是null或未定义(比如拼错变量名或加载顺序错)
注意:#{} 只安全支持基础类型(颜色、数字、字符串),不支持 map、null、function。导出前建议加 @debug 验证值存在。
立即学习“前端免费学习笔记(深入)”;
如何组织 _config.scss 并被项目级覆盖
所有全局值集中写在 _config.scss,每个变量带 !default:
$color-primary: #3b82f6 !default; $spacing-md: 1rem !default; $breakpoint-lg: 1024px !default;
入口文件(如 main.scss)中用 @use "config" with () 覆盖:
@use "@/styles/config" with ( $color-primary: #ef4444, $spacing-md: 1.25rem );
关键约束:
- 仅 Sass 1.23+ 支持
with,旧版本报错Invalid CSS after "with": expected "{", was "(" -
with中只能传字面量或已定义变量,不能传表达式(如calc(#{$spacing-xs} * 2)不合法) - 其他文件一律用
@use "config",不要重复with—— 否则覆盖失效
什么时候该导出为 CSS 变量,什么时候只用 Sass 变量
CSS 变量有运行时优势(JS 读写、主题切换),但体积和性能成本更高。别一股脑全导出。
推荐导出的场景:
- 需要 JS 动态修改的值,如
--theme-color、--font-size-scale - 需配合媒体查询做响应式变化的值(如不同断点下
--spacing-sm不同) - 暗色模式开关依赖的根级开关(
--is-dark: 1)
只用 Sass 变量的场景:
- 纯编译期计算用的中间值(如
$color-primary-dimmed: darken($color-primary, 10%)) - 组件内部固定值(按钮的
$btn-border-radius,不对外暴露) - z-index 层级表(
$z-modal: 1000)—— 运行时改 z-index 极少见,且易引发层叠混乱
避免 Undefined variable 的实际排查路径
这个报错 90% 不是变量没定义,而是作用域或加载顺序问题。
检查清单:
- 是否在
@use "config"之前就用了$color-primary?Sass 不允许前向引用 - 文件名是否为
_config.scss(带下划线)?否则可能被当作入口文件单独编译,导致变量未注入 - 路径是否相对
main.scss正确?@use "@/styles/config"和@use "@/styles/_config"在某些配置下行为不一致 - 是否误用
@import?它已废弃,且破坏模块作用域,@use才能保证命名空间隔离
最隐蔽的坑:多个 @use 链路中,某处用了 as * 提升变量到全局,结果覆盖了下游模块的同名变量——这种隐式污染极难定位。


















