.#{$var} 会编译失败,因 sass 解析器在语法分析阶段要求选择器开头必须是字母、下划线或 &,而插值 #{$var} 此时尚未展开,被视为非法空起始,导致报错 invalid css after "."。

直接在选择器里写 .#{$var} 必然报错,这不是变量没定义,而是 Sass 解析器在语法分析阶段就拒绝了这种写法——它要求选择器开头必须是字母、下划线或 &,而 #{$var} 此时还没展开,被视为空起始。
为什么 .#{$var} 会编译失败
Sass 不是在运行时拼字符串,而是在语法树构建前就卡住了。哪怕 $var: "primary" 已声明,.#{$var}-btn 仍会报错:Invalid CSS after ".": expected selector, was "#{"。这不是值的问题,是语法结构不合法。
常见错误现象包括:
- 编辑器标红,编译中断
- VS Code + Live Sass Compiler 插件静默失败,无输出 CSS
- 命令行报错位置指向选择器开头,而非变量定义处
能用的两种安全路径
真正可行的方案只有两个,且都绕开了“开头插值”这个死区:
- 固定前缀 + 插值后缀:如
.btn-#{$type}、.text-#{$size}—— 前缀.btn-是合法起始,#{$type}在其后,解析器能顺利推进 - 用
&引用父级再插值:在嵌套规则中写&--#{$modifier},然后配合@at-root提升作用域,避免生成意外嵌套结构
例如:
@each $state in ("primary", "danger") {
@at-root .btn-#{$state} {
background-color: map-get($colors, $state);
}
}
带破折号或数字开头的变量值必须 quote()
如果变量值来自 map 或 list,且含非法字符(如 "max-sm"、"2xl"),直接插值会导致 Sass 把破折号当减法、把数字开头当无效标识符,报错 Undefined variable "max" 或静默产出浏览器无法识别的选择器。
正确做法是显式包裹:
@each $key, $val in ("sm": 0.75rem, "max-sm": 0.625rem, "2xl": 2rem) {
.text-#{quote($key)} {
font-size: $val;
}
}
输出为 .text-"max-sm" —— CSS 允许带引号类名,浏览器可匹配,但部分 lint 工具会警告。不想引号?那就别让变量值含破折号或数字开头。
@extend 不能引用插值生成的类名
@extend 只认字面量选择器,不接受运行时拼接。写 @extend .btn-#{$state} 会直接报错:Invalid CSS after "@extend .btn-": expected "}", was "#{$state}"。
替代方案只有两个:
- 提前用
@each展开所有可能组合,为每个生成的类名单独写@extend - 改用
@mixin封装样式块,再在目标选择器中@include
插值产出的是静态字符串,不是运行时逻辑。你改了变量值,必须重新编译才能更新 CSS;它不参与 DOM 更新,也不和 Vue/React 的响应式系统挂钩——这点最容易被忽略。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











