max-nesting-depth在SCSS中默认不生效,因Stylelint原生仅解析标准CSS,需同时配置stylelint-scss插件和customSyntax: 'postcss-scss'才能正确识别SCSS嵌套结构并计数。

直接设 max-nesting-depth 为 3 或 4,并配齐 stylelint-scss 插件和 customSyntax: 'postcss-scss',否则规则根本不会生效——它在 SCSS 项目里默认是哑的。
为什么max-nesting-depth在SCSS里默认不工作
Stylelint 默认只解析标准 CSS 语法。遇到 &__title 这类 SCSS 特有嵌套写法时,原生解析器会直接忽略其结构层级,把整个块当成“1层”。结果就是:你写了 "max-nesting-depth": 3,但 .card { &__header { h1 { color: red; } } } 这种 4 层嵌套照样过检,零报错。
必须显式启用预处理器支持:
-
plugins: ['stylelint-scss']—— 提供对&、@mixin、@include等 SCSS 语法节点的识别能力 -
customSyntax: 'postcss-scss'—— 告诉 Stylelint “这不是纯 CSS,按 SCSS 语法树来数深度” - 漏掉其中任一,规则就静默失效,连 warning 都不会抛
max-nesting-depth到底在数什么
它不数缩进空格、不数大括号换行、也不数媒体查询内部的声明嵌套。它只统计会让选择器匹配路径变长的语法节点:
-
&(如.modal { &__body { ... } }→ +1 层) -
@media/@supports(默认计入,可用ignore: ['at-rules']排除) - 伪类/伪元素(
:hover、::before各算 +1) - 后代组合器本身不增加深度(
.card .title是 2 层,不是 3 层)
例如:.dialog { @media (min-width: 768px) { &__title { :is(h1, h2) { font-weight: bold; } } } } → 深度为 4(.dialog → @media → &__title → :is)
设成3还是4?关键看组件封装粒度
数值不是拍脑袋定的,得对应真实组件结构:
- 设为
3:适合原子化项目(如混用 Tailwind),强制扁平。允许.btn:hover(2 层),但拦住.card .card__body .card__title(3 层已到顶) - 设为
4:更现实。容纳 BEM 的典型四层:容器 → 区块 → 元素 → 状态(如.dialog .dialog__body .dialog__title :is(h1, h2)) - 设为
6或更高:等于放弃控制,.layout .sidebar .nav .item .link:hover::before这种脆弱选择器就会泛滥
注意:BEM 中 .block__element--modifier 是单个类名,不增加嵌套深度;真正危险的是靠多层后代选择器拼出来的高权重规则。
临时绕过嵌套检查的正确姿势
别用 /* stylelint-disable max-nesting-depth */ 写在块开头——它只对紧贴的下一行生效,而嵌套块通常跨多行,大概率失效。
两种可靠方式:
- 禁用下一行:
/* stylelint-disable-next-line max-nesting-depth */放在嵌套块的上一行空白处 - 块级禁用:
/* stylelint-disable max-nesting-depth */开头,/* stylelint-enable max-nesting-depth */结尾,且两行都必须紧邻实际 CSS 内容(不能空行隔开)
最常被忽略的一点:这种禁用只影响深度计算,不解决根本问题——如果某处真需要 5 层语义,优先用 @at-root 提级,而不是加深嵌套。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











