浏览器从右往左匹配,嵌套越深回溯越耗CPU:写.page .main .content .card .title时,浏览器先遍历所有.title元素,再逐层向上验证父级,DOM节点越多越卡顿,Recalculate Style飙升、滚动掉帧、hover卡顿,低端Android设备上比.card__title慢4倍以上。

浏览器从右往左匹配,嵌套越深回溯越耗 CPU
写 .page .main .content .card .title 这种 5 层选择器时,浏览器不是先找 .page 再往下钻,而是先遍历所有 .title 元素,再对每个 .title 向上检查是否在 .card 内、该 .card 是否在 .content 内……每多一层,就多一次 DOM 树向上遍历。DOM 节点越多(比如商品列表有 200 个 .title),这个过程就越吃 CPU。
常见错误现象:Recalculate Style 时间在 Chrome DevTools Performance 面板里突然飙升;滚动掉帧;hover 响应发卡——尤其在低端 Android 设备上,这类选择器可能比 .card__title 慢 4 倍以上。
特异性失控让 JS 动态加类和调试都变困难
.a .b .c .d 的 specificity 是 0,0,4,0,而单类名 .d 只有 0,0,1,0。高权重直接带来两个现实问题:
- 后续用 JS 动态加类(如
el.classList.add('is-hidden'))很难覆盖它,往往得加!important或写更重的选择器 - DevTools 里“已计算样式”面板中,真正生效的规则常被压在十几条被覆盖的旧规则底下,人工定位要反复验证父级路径是否成立
- VS Code 的 CSS Peek 功能对深层嵌套支持弱,点击跳转常停在错误层级
SCSS/Less 的 & 不是作用域保护,用错反而加重耦合
& 是父选择器的完整副本,不是缩进作用域。误用会生成更重、更耦合的选择器:
立即学习“前端免费学习笔记(深入)”;
- ✅ 安全:
.btn { &__icon { display: inline-block; } }→ 编译出.btn__icon(权重0,0,1,0) - ✅ 安全:
a { &:hover { color: blue; } }→a:hover(伪类不增加层级计数) - ❌ 危险:
.modal { & .close { opacity: 0.5; } }→.modal .close,多一层无意义后代关系,权重+1 - ❌ 危险:
.list { & li { margin: 4px; } }→ 实际仍是.list li,&完全没起作用
@at-root 不是用来“救”深层嵌套的
@at-root 的作用是切断当前嵌套链对后续规则的前缀继承,不是给 4 层缩进打补丁。它只适合两种场景:
- 媒体查询内提级:
.btn { @at-root @media (min-width: 768px) { &--large { font-size: 18px; } } } - 脱离父级上下文:
.modal { .overlay { @at-root .tooltip { top: -10px; } } } - 看到
.card { .body { .title { .highlight { } } } }就想加@at-root——第一反应应是删掉两层缩进,改用.card { &__title { } }


















