嵌套应限制在3层内,即容器、组件、状态/伪类;慎用&符号避免特异性失控;BEM提供语义骨架,Sass嵌套仅辅助紧凑书写;禁用过度嵌套以防维护困难和样式覆盖风险。

嵌套层级超过3层时,CSS选择器会失控
嵌套本身不难,难的是控制嵌套深度。Sass允许无限嵌套,但编译后生成的选择器可能变成 .header .nav .item .link:hover 这种长链,既难维护,又容易被其他样式意外覆盖。
实操建议:
立即学习“前端免费学习笔记(深入)”;
- 把嵌套限制在3层以内——外层容器、组件、状态/伪类,例如
.card→&__title→&:hover - 避免用嵌套模拟DOM结构(比如
article > section > p > em),这类关系应该靠语义化BEM类名或单独模块管理 - 用
@at-root提前跳出嵌套,比如在.modal里写全局body.is-modal-open时必须这么做,否则编译结果是无效的.modal body.is-modal-open
Sass中 & 符号的常见误用场景
& 看似简单,但它是嵌套逻辑的“锚点”,不是单纯拼字符串。很多人以为 &.is-active 就是加个类,却没意识到它依赖父选择器是否带空格。
实操建议:
立即学习“前端免费学习笔记(深入)”;
-
&.is-active编译为.btn.is-active(同元素多类);& .is-active(注意空格)则变成.btn .is-active(后代选择器) - 在伪元素中写
&::before没问题,但写&:not(.disabled)::before时要小心——如果父选择器是.btn,结果是.btn:not(.disabled)::before,可读性还行;但如果父是.btn-group,就容易让人误读成“整个组不可用”,实际只是单个按钮 - 慎用
& + &这类兄弟选择器嵌套,它会让意图模糊,不如直接写.item + .item
BEM命名和Sass嵌套如何真正配合
纯靠嵌套不解决语义混乱,BEM才是结构骨架。Sass嵌套只是让BEM写法更紧凑,而不是替代它。
实操建议:
立即学习“前端免费学习笔记(深入)”;
- 用
@use "sass:selector"配合selector.append()动态拼接修饰符类(如.btn--primary),但仅限简单组合;复杂状态仍推荐显式声明 - 块级类名(
.card)作为嵌套根,元素类(&__header)和修饰符(&--compact)必须直出,不套子嵌套——.card--compact &__header是对的,.card--compact { &__header { ... } }就多余了 - 当需要覆盖第三方库样式(比如
react-datepicker),别用嵌套去硬套它的DOM路径,而是用!important或更高优先级类名,嵌套只会放大耦合风险
编译后CSS体积和选择器特异性陷阱
嵌套越多,生成的选择器特异性(specificity)越高,后期想用简单类名覆盖它,就得写更长的选择器或加 !important,形成恶性循环。
实操建议:
立即学习“前端免费学习笔记(深入)”;
- 用
sass --watch配合--style=expanded查看真实输出,重点检查是否有重复父类(如.page .page .content)——这通常是因为在已嵌套上下文中又用了& - 禁用
!optional(Sass 1.70+ 的实验特性),它会让嵌套行为更难预测;坚持用明确的&和空格控制作用域 - 团队项目里统一配置
stylelint规则,比如selector-max-compound-selectors: 2,从工具层卡住过度嵌套
嵌套不是为了少写几个点,而是让样式意图和DOM结构、命名约定三者对齐。一旦发现要靠注释解释某段嵌套“为什么这么写”,基本就是结构该拆了。


















