SCSS中必须禁用&嵌套以保障BEM类名可搜索性、IDE跳转及Vue scoped样式生效,所有类名须以完整字符串显式书写,如.card__title而非&__title。

SCSS中&嵌套会破坏类名可搜索性
直接写 &__title 看似省事,但编译后生成的 .card__title 在全局搜索时根本搜不到——因为你在 SCSS 文件里搜的是 &__title,而实际生效的 CSS 类名是字符串拼接结果,IDE 无法跨文件、跨编译阶段做语义索引。更糟的是,如果外层还有 .dashboard .layout 嵌套,&__title 会产出 .dashboard .layout .card__title 这种带空格的选择器,DevTools 里点“.card__title”根本跳不回源码。
必须用显式类名替代&拼接
所有 BEM 类名必须在 SCSS 中以完整字符串形式出现,否则搜索、跳转、lint 校验全部失效。这不是风格问题,而是工具链依赖的硬性前提。
- ✅ 正确:
.card { .card__title { color: #222; } }—— 搜索card__title能立刻定位 - ❌ 错误:
.card { &__title { color: #222; } }—— 搜索card__title找不到,IDE 不识别该字符串 - ⚠️ 特别注意:
.card { @at-root .card__title { } }仍算显式,可搜;但@at-root .card#{'__'}title这类插值写法同样不可搜
Vue 单文件组件中&导致 scoped 失效
Vue 的 <style scoped> 依赖类名字符串静态可析,一旦用 &__header,编译器无法提取出 user-card__header 这个完整 token,导致 data-v-xxx 属性不会注入到对应 DOM 元素上,样式彻底丢失。
- 必须严格按文件名对齐 Block 名:UserCard.vue → 只能写
.user-card__header,不能靠&__header推导 - 动态类名也得走显式路径:
:class="['user-card__header', isSticky ? 'user-card__header--sticky' : '']" - 封装的
cn()函数输出必须是字面量字符串,不能含运行时拼接(如`${block}__header`)
stylelint 必须校验显式类名而非&语法
stylelint-selector-bem-pattern 插件只检查最终 CSS 输出是否符合 BEM 结构,它不关心你是不是用了 &。但如果你靠 &__item 写 SCSS,就等于放弃编辑器实时高亮、Ctrl+Click 跳转、全局类名引用统计这些基础能力。
立即学习“前端免费学习笔记(深入)”;
- CI 中启用
--max-warnings 0是底线,但 lint 通过 ≠ 可维护 —— 它拦不住&__body这种写法 - 真正要加的检查是自定义规则:禁止在 SCSS 中出现
&__或&--后紧跟字母/数字(可用正则/&(__|--)[a-zA-Z0-9]/) - VS Code 插件
stylelint-plus默认不报&__title,需手动开启selector-bem-pattern的 strict 模式并绑定到 .scss 文件
&,把每个 __ 和 -- 都打出来,搜索才不会卡在空白结果页。


















