bem能锁死选择器权重为0-1-0,因其强制仅用单类名选择器(如.button__icon--loading),禁用空格、标签、id及后代选择器;一旦违规(如.button .button__icon)即破防,权重升至0-2-0或更高。

为什么BEM能锁死选择器权重为0-1-0
BEM本身不“提升”权重,而是通过禁止空格、标签、ID和后代选择器,把所有有效规则的 specificity 严格控制在 0-1-0。只要写对,.button__icon--loading 和 .button 权重完全相等,不存在谁覆盖谁——冲突根本没机会发生。
常见破防点:
-
.button .button__icon:多一个空格,权重立刻变成0-2-0 -
button.button__icon:加了标签名,权重升到1-1-0,且一旦框架换用span渲染按钮,样式直接失效 -
#header .button:ID 一出现,权重跳到1-1-0,整套 BEM 权重可控性归零
SCSS嵌套是BEM权重失控的最大源头
写 .button { &__icon { } } 是安全的,但写 .button { .button__icon { } } 或 .button { .icon { } } 就等于亲手给 BEM 打补丁再捅一刀——编译结果全是 .button .button__icon 这类高权重选择器。
实操红线:
- 所有
&__xxx必须紧贴块定义,中间不能有空行或注释,否则&失效 - 禁用超过 2 层的嵌套:
.modal { .header { .title { } } }→ 必须拆成.modal__title+@at-root提级 -
@media块内禁用&__xxx,否则外层若有.layout .dashboard,会炸出 6 层选择器 - 检查编译后 CSS:发现
.a .b .c .d这种带空格的长链,立刻回溯 SCSS 源文件删嵌套
Modifier 生效失败,90%不是BEM问题,是HTML或加载顺序错了
.button--primary 单独写无效,是因为 Modifier 不是独立样式单元。它必须和基础 Block 类共存,且 CSS 声明顺序必须是 Block 在前、Modifier 在后。
典型错误:
- HTML 只写
class="button--primary",漏掉button—— 浏览器根本找不到匹配目标 - CSS 文件里
.button--primary写在.button上面,层叠顺序错乱 - 构建工具(如 css-loader)配置了
localIdentName但没保留双下划线,.button__icon被转成.buttonicon_abc,类名失配 - 全局通配规则(如
body * { color: red !important })直接碾压所有0-1-0权重
工具链必须卡住出口,不能靠人自觉
靠文档、培训、口头提醒,三个月后基本清零。真正起效的是工程化拦截:
- 在
stylelint中启用plugin/selector-bem-pattern,自动报错:.header .logo、.btn-primary、CardTitle、_input - CI 流程加
npx stylelint "**/*.{css,scss}",失败即阻断 PR 合并 - VS Code 安装
BEM Tools插件,输入buttonTab 自动补全button__text和button--disabled,不支持button_text或button-text - ESLint 配合
selector-class-pattern规则,正则强制匹配^[a-z][a-zA-Z0-9]*(__[a-z][a-zA-Z0-9]*)?(--[a-z][a-zA-Z0-9]*)?$
最常被忽略的一点:只要有人在项目里加了一次 !important,整个 BEM 的 modifier 覆盖链就不可信了——后续所有调整都会被迫跟进,最终谁都压不住谁。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











