BEM通过强制单类名选择器使所有有效规则权重恒为0-1-0,彻底消除权重竞争;一旦出现空格、标签或ID选择器即破防, modifier须与block共存且依赖声明顺序生效。

它不能“彻底解决”——BEM 本身不解决冲突,它让权重冲突这件事**失去发生条件**。只要严格遵循规则,所有有效选择器的 specificity 恒为 0-1-0,没有高低之分,自然不存在“谁压过谁”的问题。
为什么 BEM 选择器权重一定是 0-1-0
BEM 要求所有 CSS 规则必须以单个类名为唯一选择器,比如 .button__icon--loading。浏览器计算 specificity 时,只统计 class 的数量,这里只有 1 个,结果就是 0-1-0。一旦出现空格(如 .button .button__icon)、标签名(如 button.button__icon)或 ID,权重立刻跳到 0-2-0 或更高,BEM 的权重控制即失效。
- 合法:
.search-form__submit、.search-form__submit--disabled、.search-form__submit:hover(权重0-1-1,仍可控) - 破防:
.search-form .search-form__submit(0-2-0)、div.search-form__submit(1-1-0)、#main .button(1-1-0)
.button--disabled 为什么单独写无效
Modifier 不是独立样式单元,它必须与基础 Block 类共存,才能在层叠顺序中被正确应用。CSS 文件里 .button 规则必须先声明,.button--disabled 后声明;HTML 中也必须写成 class="button button--disabled",否则浏览器根本找不到匹配目标。
- ✅ 正确:HTML 有
class="button button--disabled",CSS 中.button在前、.button--disabled在后 - ❌ 失效:HTML 只有
class="button--disabled",或 CSS 文件加载顺序颠倒 - ⚠️ 隐患:构建工具(如 css-loader)若配置
localIdentName时未保留双下划线,.button__icon可能被转成.buttonicon_abc,直接导致类名失配
DevTools 里看到样式被划掉,真不是 BEM 失效
90% 的“覆盖无效”现象,源头不在 BEM,而在外部干扰:全局通配规则(如 body * { color: red !important })、第三方主题的 !important、或泛化选择器(如 .theme-dark .card .title)。BEM 的 0-1-0 权重无法赢过 !important,也不该去赢——它的设计前提就是「不依赖优先级竞争」。
立即学习“前端免费学习笔记(深入)”;
- 排查路径:打开 DevTools → “Computed” 面板 → 点击被划掉的属性 → 右键 “Reveal in Sources” 定位真实来源
- 关键防线:禁用所有
*、body、div开头的全局样式;第三方组件用 wrapper block 隔离,不直接改其类名 - 最常被忽略的一点:只要有人加了一次
!important,整个 BEM 的 modifier 覆盖链就不可信了——后续所有调整都会被迫跟进,最终谁都压不住谁
真正难的不是写对 BEM,而是守住那条线:不为空格让步,不为“快速修复”妥协,不把构建工具当黑盒。权重恒定不是语法特性,是纪律结果。


















