max-nesting-depth 规则检查 CSS/SCSS/Less 中选择器的嵌套层级,仅统计 &、@media、@supports、伪类/伪元素等导致结构变深的节点,不检查声明块缩进或媒体查询内部嵌套;设为3或4是常见安全值,需配合stylelint-scss插件和customSyntax配置才对SCSS生效。

max-nesting-depth 规则到底检查什么
max-nesting-depth 检查的是 CSS(或 SCSS/Less)中选择器的嵌套层级,不是 CSS 声明块的缩进,也不是媒体查询内部的嵌套——它只数 &、@media、@supports、伪类/伪元素等导致选择器结构变深的语法节点。比如 .card .card__header h1 算 3 层,而 .card { &__header { h1 { ... } } } 在 SCSS 中算 4 层(.card → &__header → h1 → 声明)。
为什么设成 3 或 4 是常见安全值
设太高(如 6)会让组件样式失控,容易出现类似 .layout .sidebar .nav .item .link:hover::before 这种脆弱选择器;设太低(如 1)又会误伤合理嵌套(比如 .btn:disabled 或 .modal .modal__content)。实际项目中:
-
3适合强调原子化、CSS-in-JS 或 utility-first(如 Tailwind)风格的项目 -
4更贴近传统组件封装场景,允许一层父容器 + 一层区块 + 一层元素 + 一层状态(例如.dialog .dialog__body .dialog__title :is(h1, h2)) - 若用 SCSS,需配合
stylelint-scss插件,否则&嵌套不被识别为深度增加
在 stylelint.config.js 中正确启用该规则
直接写 "max-nesting-depth": 3 不够——它默认只对纯 CSS 生效。要支持 SCSS/Less,必须显式配置解析器和插件:
/** @type {import('stylelint').Config} */
export default {
plugins: ['stylelint-scss'],
customSyntax: 'postcss-scss', // 或 'postcss-less',不可省略
rules: {
'max-nesting-depth': [3, {
ignore: ['at-rules'], // 允许 @media/@supports 不计入深度
severity: 'error'
}]
}
};
注意:customSyntax 必须与你项目实际语法匹配,否则 max-nesting-depth 会静默失效,连报错都没有。
立即学习“前端免费学习笔记(深入)”;
忽略局部嵌套时别踩 /* stylelint-disable */ 的坑
临时绕过某段嵌套,不能只写 /* stylelint-disable max-nesting-depth */ 就完事。它只对当前行生效,而嵌套往往跨多行。正确做法是:
- 用
/* stylelint-disable-next-line max-nesting-depth */放在嵌套块的上一行 - 或用块级注释:
/* stylelint-disable max-nesting-depth */开头,/* stylelint-enable max-nesting-depth */结尾 - 绝对不要在
@media内部写/* stylelint-disable */后就以为整个媒体查询都豁免了——规则仍会对其中每个选择器单独计层
真正难控制的是跨文件继承(比如 SCSS @use 引入的模块里带嵌套),这种场景 max-nesting-depth 无能为力,得靠约定或拆分职责来约束。


















