Sass嵌套超3层或混用ID选择器是导致编译后CSS选择器权重过高的主因;应严格限制嵌套深度、禁用ID样式、善用BEM与&符号精准控制输出。

直接说结论:Sass编译后选择器权重高,90%是因为嵌套层数超过3层,或混用了ID选择器;不是Sass有问题,是你写的嵌套在悄悄拼出 .page .section .content .item .title 这种0-4-1权重的选择器。
为什么嵌套3层就该停手
Sass的嵌套不是“写得像HTML结构”,而是“生成什么CSS”。浏览器匹配选择器是从右往左算的,.a .b .c .d .e 要比 .e 多做4次父级查找,老设备上滚动卡顿、Lighthouse报“Avoid overly specific selectors”都源于此。
- 嵌套每多一层,特异性(specificity)就+1个类级分(即0-1-0 → 0-2-0)
-
.card { .header { .title { color: red; } } }编译为.card .header .title,权重0-3-0;而.card__title只有0-1-0 - VS Code里按住Ctrl点击编译后的CSS文件,直接看生成结果——别靠猜
- 用
stylelint-config-sass-guidelines配置max-nesting-depth: 3,保存即报错
ID选择器在Sass里是重量级炸弹
ID选择器单个就值100分(0-100-0),一旦进嵌套,权重直接失控。比如 #app .user-panel .btn 是0-101-1,你后面加10个class都压不住它。
- 永远不要写
#header { .nav { ... } }—— 编译后是#header .nav,权重碾压所有组件类 - Vue/React项目里,
id应只用于锚点跳转或ARIA关联,不参与样式控制 - 想“唯一标识”?用BEM修饰符:
.modal--fullscreen,不是#modal-fullscreen - 第三方库带ID样式(如某些富文本编辑器)?用属性选择器局部覆盖:
[data-editor="quill"] .ql-toolbar,比#quill-editor .ql-toolbar安全得多
& 符号的常见误用:你以为在缩写,其实在增重
& 不是“当前块的语义”,而是“父选择器字符串原样拼接”。这个误解导致大量冗余权重。
立即学习“前端免费学习笔记(深入)”;
- 错误:
.btn { .icon { &--small { ... } } }→.icon--small,但&此时指.icon,不是.btn,结果丢失上下文 - 正确写法:
.btn { &__icon { &--small { ... } } }→.btn__icon--small,干净且可控 - hover改子元素别重复写类:
&:hover .btn__text错,应写&:hover &__text→.btn:hover .btn__text,语义对且权重不跳变 - 兄弟选择器也一样:
.card { & + & { margin-top: -1px; } }→.card + .card,不引入额外父级
真正难的不是写几层嵌套,而是每次敲 { 前问一句:这个层级,是业务语义必需的,还是仅仅因为“HTML里它就在里面”?BEM的 __ 和 -- 是边界线,跨过去就得拆模块,不是加嵌套。


















