SCSS中&必须紧贴前字符,空格会导致失效;子选择器须显式用&绑定,否则成顶层规则;HTML class名需与编译结果严格匹配;嵌套过深或误用@at-root易引发路径爆炸。
SCSS 里 & 必须紧贴前一个字符,中间不能有任何空格。一旦加空格,Dart Sass 就不再把它当作父选择器引用,而是当成新选择器的起点——结果要么编译出孤立类(比如 .header 而不是 .card .header),要么直接报错。
常见错误写法:
.card { & .header { } } → 编译为 .card .header,但 & 实际没参与拼接,纯属冗余占位.btn { & :hover { } } → 报错 SassError: Invalid CSS after "&": expected "{", was ":hover"
.modal { &:focus { } } 正确;.modal { & :focus { } } 错误(空格在中间)SCSS 不靠缩进“猜”关系,它只认显式绑定。如果子选择器开头不含 &、@at-root 或明确关系符(如 >、+、~),它会被当作文档根级的新规则处理,导致生成非法或无效选择器。
典型现象:
立即学习“前端免费学习笔记(深入)”;
.emotion { __text { color: blue; } } → 编译出 __text { }(浏览器直接忽略,因为不是合法选择器).card { .card__body { padding: 1rem; } } → 生成 .card .card__body,但已脱离 BEM 拼接逻辑,权重变高.emotion { &__text { color: blue; } } → .emotion__text
SCSS 编译只管你写了什么 class 名,不管 HTML 里有没有对应结构。样式“不生效”,90% 是 class 名脱节,不是语法错。
例如:
.card { &__body { padding: 1rem; } } → 输出 .card__body { }
<div class="card"><div class="body"></div></div> → .card__body 根本没匹配目标class="card__body"(改 HTML),或改 SCSS 为 .card .body { }(放弃 BEM 拼接)超过 4 层嵌套时,& 会展开整条父路径,生成像 .layout .dashboard .card .header__title:hover 这种长选择器。它不仅体积大、难调试,而且浏览器匹配效率低,DOM 结构一动就断。
更隐蔽的问题是 @at-root 用错位置:
.modal { @at-root .u-text-center { text-align: center; } } → 正确输出 .u-text-center
.modal { @at-root (with: .theme-dark) { .button { color: white; } } } → 输出 .theme-dark .button,可控@media 块里嵌套再用 &,比如 @media (min-width: 768px) { .card { &__title { &:hover { } } } },& 会把外层所有嵌套都拖进来,路径失控& 是否紧贴、有没有空格、有没有漏掉关系符——这些地方错一个,父级就彻底丢了。