bem不降低特异性,而是锁死为0-1-0——所有选择器均为单类名,权重恒定,冲突仅由层叠顺序决定;破规如空格后代、标签+类、多类叠加均破坏该前提。

能,但不是靠“降低”,而是让所有选择器的特异性恒定为 0-1-0 —— 所有规则权重一致,冲突不再靠“谁更重”决定,只看层叠顺序。
为什么BEM不降低特异性,而是锁死它
BEM本身不改变CSS权重计算规则,它靠强制约束写法来消除变量:只要所有有效选择器都是单个类名(如 .button__icon),浏览器算出来的 specificity 就永远是 0-1-0。没有 .block .element 这种空格后代、没有 button.button__submit 这种标签+类组合、也没有 #nav 这种ID——这些才是把权重拉高到 0-2-0、1-1-0 甚至 1-0-0 的元凶。
常见破规现象:
-
.card .card__title:看似合理,实则权重升至 0-2-0,且 DOM 结构一动就失效 -
h3.card__title:标签 + 类 = 权重 1-1-0,破坏 BEM 的扁平前提 -
.button--primary.button--loading:两个类叠加,权重 0-2-0,应合并为.button--primary--loading或拆成独立规则
修饰符(Modifier)必须和基础类共存
单独写 .button--disabled 是无效的——它不是独立样式单元,而是对 .button 或 .button__icon 的状态补充。浏览器匹配时,.button--disabled 自身权重虽仍是 0-1-0,但若 HTML 中漏掉基础类,样式根本不会生效。
实操要点:
- HTML 必须同时存在:
class="button button--disabled"或class="button__icon button__icon--hidden" - CSS 规则顺序不能乱:
.button--disabled必须在.button之后声明,否则层叠不生效 - 禁止用 JS 只加 Modifier 类:
el.classList.add('button--disabled')前必须确保el.classList.contains('button')
BEM权重稳定的三个隐性依赖
0-1-0 不是写对命名就自动成立,它依赖构建链与运行时协同:
-
css-loader配置里localIdentName必须保留双下划线,比如[name]__[local]___[hash:base64:5];若配成[hash],.menu__item可能被转成.menuitem_abc123,直接破防 - 第三方组件引入时,不能靠
.my-block :deep(.ant-btn)这种穿透写法去覆盖——它生成的选择器含空格,权重失控;正确做法是包一层div class="my-block",再用.my-block .ant-btn(虽破BEM,但权衡之下更可控) - 遇到
!important别硬顶,它会切断整个 BEM 的 modifier 覆盖链;优先查是否第三方样式已锁死,再决定是否用 wrapper 隔离
真正难的不是记住 __ 和 -- 怎么写,而是团队敢不敢删掉那行 #header,以及构建工具敢不敢拒绝编译任何含空格的选择器。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











