结论:scss 中 :has() 等新伪类不能嵌套在 & 后拼接,必须作为完整选择器独立书写(如 .card:has(.badge) { ... }),否则 dart sass 会因不识别而误解析;嵌套缩进不统一、@use 位置/路径错误、混用 node sass 与 dart sass 也是常见根源。

直接说结论:这类错误几乎都不是 CSS 本身写错了,而是 Sass 编译器在解析 SCSS 语法时卡在了嵌套、@use、变量作用域或新 CSS 特性混用这几个关键点上。
嵌套缩进不合法导致“Invalid CSS after”
错误现象常见为 Invalid CSS after "...": expected "{", was "}" 或类似提示,本质是 Dart Sass 把换行缩进当成了嵌套结构,但对齐不一致导致解析中断。
- 所有嵌套层级必须用统一数量的空格(推荐
2或4),禁用 Tab,也禁止空格 + Tab 混用 -
&必须紧贴上一行末尾,&:hover正确,& :hover(中间有空格)直接报错 - 别在
{后换行再缩进——SCSS 不需要花括号,换行即表示嵌套开始,多此一举反而触发语法歧义 - VS Code 用户建议装
EditorConfig for VS Code插件,配置indent_style = space和indent_size = 2
@use 位置或路径错误引发变量/函数不可见
不是变量没定义,而是 @use 没生效,导致后续引用被当成裸字符串输出,浏览器收到 color: $primary; 这种无效 CSS,控制台报 Invalid property name。
-
@use必须位于文件最顶部,不能包裹在@media、@if或嵌套块里 - 路径必须正确,比如
@use "@/styles/vars.scss" as *;,且vite.config.ts中resolve.alias已配好@指向src -
vars.scss里只能有$xxx、@mixin、@function,不能出现body { }这类真实 CSS 规则 - 调试可用
@debug $var插入嵌套块开头,确认是否注入成功
把 :has()、:is() 当 SCSS 嵌套写导致误解析
Dart Sass 不校验最终 CSS 是否合法,但它会尝试把 &:has(.badge) 当作 SCSS 选择器片段来解析——而 :has() 是浏览器运行时才理解的伪类,Sass 根本不认识。
- 所有以
:开头的新伪类(:has、:is、:where)必须作为完整选择器出现,不能放在&后拼接 - 正确写法是单独写:
.card:has(.badge) { ... },而不是嵌套在.card { &:has(.badge) { ... } } - 若需条件样式,改用
@if $supports-has { ... },由构建脚本注入该变量,而非依赖 CSS@supports selector() - 真正处理这些特性的位置是 PostCSS:确保
postcss-preset-env已启用,stage: 4
从 Node Sass 迁移后突然报错:其实是旧宽容被清零了
Node Sass(LibSass)早已停更,它对语法错误很“佛系”,漏分号、& 后多空格、非法插值都可能悄悄放过;Dart Sass 则严格执行规范,迁移后问题集中暴露。
- 立刻卸载
node-sass和旧版sass-loader,安装sass(Dart Sass)和sass-loader@^13 - 检查配置中是否残留
implementation: require('node-sass')或nodeSass字段 -
@import必须全部替换为@use,且@use不能出现在@mixin内部或条件语句中 - 中文变量名(如
$主色)在词法分析阶段就失败,Sass 不支持任何非 ASCII 字母开头的变量名,无法绕过
最易被忽略的是:错误行号往往指向“下游”使用处,但根因在上游 @use 路径错、变量文件混入了 CSS 规则、或嵌套缩进在某处悄悄变了。定位时优先用 sass --trace your.scss 看栈顶第一行,而不是只盯报错信息里的“expected”。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











