浏览器从右往左匹配选择器,4层嵌套是性能拐点;&\_\_title失效源于html未按bem规范书写block类名;深层嵌套中&会叠加权重,应优先用@at-root提级实现扁平化。

浏览器从右往左匹配选择器,4层就是性能拐点
这不是SCSS编译慢,而是它生成的CSS在运行时被浏览器反复回溯验证。比如 .page .main .content .card .title,浏览器得先找所有 .title 元素,再逐个向上检查是否同时满足 .card → .content → .main → .page。DOM节点越多、更新越频繁(如滚动列表),这个链路耗时越明显。
实测显示:3层嵌套(如 .card .header .title)尚可接受;一旦到4层,样式计算时间常翻倍,低端Android设备上已可见卡顿。这不是理论值,是Chrome DevTools Performance面板里能直接观测到的渲染延迟跳变点。
&__title 编译失效,往往是因为HTML没写对类名
&__title 编译后是 .card__title,但这条规则只在HTML同时存在 class="card" 和 class="card__title" 时才生效。常见错误包括:
- HTML只写了
<h2 class="title"></h2>,漏掉card块名 - 写了
<h2 class="card__title"></h2>却没包在<div class="card"> 里 <li>嵌套中误用空格:<code>.card { .header { &__title { } } }→ 编译出.header__title,不是想要的.card__title -
.theme-dark { .menu { &__item { } } }→ 编译为.theme-dark .menu .menu__item(权重 0-3-0) - 后续想用
.menu__item.is-active覆盖,根本压不住——得写成.theme-dark .menu .menu__item.is-active才行 - 真正安全的
&用法只限于单层块内:.card { &__title { } &--compact { } } - 错误写法:
.theme-dark { .card { &__title { } } }→ 生成4层选择器 - 正确提级:
.theme-dark { @at-root .card__title.theme-dark { } }→ 单类+修饰符,2层以内 - 媒体查询里禁用
&嵌套:@media (min-width: 768px) { .card__title { display: block; } },别再套&__subtitle
本质不是SCSS语法错,而是BEM语义断链:Block类名必须显式出现在HTML中,且是独立存在的类,不能靠嵌套“推导”出来。
嵌套不等于作用域,& 会把整条父路径拼进去
& 不是“当前模块前缀”,而是“上一层选择器的完整字符串”。在深层嵌套里,它会把权重一起带进来:
超过2层嵌套还硬用 &,就是在埋权重炸弹,后期维护成本指数级上升。
重构建议:用 @at-root 提级,而不是靠缩进假装隔离
当某段样式逻辑上属于组件、但不该继承父路径时,@at-root 是比嵌套更干净的解法:
BEM扁平化不是为了“好看命名”,而是让每个CSS规则只依赖一个类名,彻底绕过浏览器的向上回溯。这点最容易被忽略:删DOM层级没用,关键得让CSS选择器本身变短。











