嵌套超3层会导致选择器长度爆炸式增长,浏览器匹配性能下降;&符号误用会错误复制父级上下文;@extend在深层嵌套中引发选择器复制爆炸;压缩模式无法解决嵌套滥用问题。

嵌套超3层会让选择器长度爆炸式增长
每多一层嵌套,Sass就机械地在编译后CSS中拼接一个后代选择器(空格分隔)。比如 .page 套 .section 再套 .card,最终生成 .page .section .card——这不是“写得更细”,而是把选择器从1个类变成3个类连续匹配。浏览器匹配时要逐层向上验证,DOM越深、更新越频繁,性能损耗越明显。Lighthouse报“Avoid overly specific selectors”就是这个原因。
&符号误用会悄悄复制父级上下文
& 只代表**紧邻上一层的选择器字符串**,不是视觉缩进里的“最外层”。常见错误:.card { .header { &__title { } } } 本意是生成 .card__title,实际却输出 .header__title(因为 & 指向 .header)。更糟的是,如果 HTML 里没写 class="header",这条规则根本不会生效,但开发者常误以为是“样式没加载”,反复加 !important。
- 有空格:
.card { .title { &--large { } } }→ 编译为.title--large - 没空格:
.card { &__title { } }→ 编译为.card__title - 想保留外层?用变量:
$block: ".card"; #{$block}__title { }
@extend 在深层嵌套里会触发选择器复制爆炸
@extend 不是“复用”,而是编译期把所有引用它的选择器机械拼在一起。比如 .modal 和 .card 都 @extend %flex-center,结果生成 .modal, .card { display: flex; ... } —— 看似省代码,实则让每条规则都带上完整祖先链:.layout .sidebar .modal, .layout .sidebar .card。一旦嵌套已深,@extend 就像往火堆里倒油。
- 真正该用
%placeholder的场景:稳定、语义明确的基础样式(如清浮动、居中) - 禁止对动态类名(如
.btn--<code>size)用@extend,Sass不支持运行时扩展 - 跨文件
@extend必须用@use显式导入,且目标必须是%开头
压缩模式根本救不了嵌套滥用
开 --style compressed 只删空格换行,不碰选择器结构。哪怕你写了100层嵌套,它也只会把 .a .b .c ... .z 挤成一行,体积照旧。真正膨胀的源头是源码:嵌套过深 + @extend 泛滥 + 工具类循环生成。检查输出 CSS,如果发现同一组声明(如 margin: 0.5rem)重复出现几十次,基本就是 @extend 或嵌套失控了。
立即学习“前端免费学习笔记(深入)”;
- 务必关掉
sourceMap:默认开启时会在文件末尾追加 base64 字符串,直接+100KB+ - Webpack 项目中,压缩必须写在
sassOptions.outputStyle: 'compressed',不能只靠后续cssnano - 用
gzip -c main.css | wc -c测真实体积——如果 gzip 后仍远超预期,说明内容冗余,不是格式问题
{ 前,得想清楚:这一层嵌套,到底是表达组件内部语义关系,还是在模拟 DOM 树深度?前者值得,后者迟早要拆。


















