bem类名权重恒为0,1,0,样式覆盖靠声明顺序而非权重提升;错误写法如.button .button--disabled破坏语义且不增权,正确应为独立单类选择器并确保后声明;失效主因通常是html未加类、css加载顺序错或内联样式干扰,非权重不足。

所有BEM类名权重严格为0,1,0
BEM强制只用单个class选择器,比如.button、.button__icon、.button--disabled——它们的CSS specificity全是0,1,0。浏览器不比谁“更重”,只看谁声明在后,“最后声明者胜出”这条规则就足够稳定覆盖。
常见错误是写.button .button--disabled,看着像提权,其实权重还是0,1,0,语义却断了:修饰符脱离宿主元素,HTML里加了button--disabled也白搭;更糟的是,两个0,1,0规则纯靠加载顺序决定胜负,一旦CSS文件引入顺序错位,样式就失效,开发者第一反应就是加!important救火。
- ✅ 正确写法:
.button { opacity: 1; }→.button--disabled { opacity: 0.4; }(后者排在前者之后) - ❌ 错误写法:
.button.is-disabled(双类名不违规但无增益)、.button span(权重升为0,1,1)、#main .button(权重1,1,0,破坏BEM隔离) - ⚠️ 注意:
:is()或:where()不能替代BEM——:is(.header .nav a)仍带高权重,且DevTools里更难定位来源
.button--disabled没生效,99%不是权重问题
你写的.button--disabled { opacity: 0.4; }没起作用,大概率不是因为“权重不够”,而是三件事没对上:
- HTML元素上根本没加上
button--disabled这个类——JS拼错了,比如写成className="button disabled"而不是button--disabled - CSS文件引入顺序反了:
button.css在theme.css之后加载,结果.button默认规则后声明,把.button--disabled盖掉了 - DevTools里看到的computed值来自内联
style属性或JS动态注入的样式,这类声明优先级高于任何外部CSS(包括!important)
每次想加!important前,先打开DevTools Styles面板,点开被划掉的属性,看右边“specificity”数字——如果.button--disabled已经是0,1,0且排在目标规则之后,那问题一定不在CSS本身。
第三方组件样式冲突时,别硬刚!important
Ant Design、Element Plus这些库真用了!important,你不需要跟着用。BEM给的是隔离能力,不是对抗能力。
- ❌ 别写:
.ant-btn { border-radius: 0 !important }——等于把你的样式绑死在第三方命名上,升级库就崩 - ✅ 正确做法:用容器封装,比如
<div class="my-form__submit-wrapper"><button></button></div>,再写.my-form__submit-wrapper .ant-btn - ✅ 更稳:配合CSS Modules或构建时自动加哈希,确保
.my-form__submit-wrapper .ant-btn的作用域不泄漏 - ⚠️ 极端情况:对方真用了
!important,你只能也用——但必须锁死范围:.my-form__submit-wrapper .ant-btn--override,绝不用全局选择器
修饰符不是兜底覆盖开关
--disabled、--loading这类修饰符,本质是状态标识,不是用来“压过默认样式”的补丁工具。一旦你在.button--disabled里塞!important,后续加暗色主题就得写.theme-dark .button--disabled { ... !important },再加响应式又要叠一层——恶性循环从这里开始。
真正该检查的是:.button--disabled是否排在.button之后?HTML是否真加了这个类?有没有其他更高specificity的选择器(比如[class*="button"])在暗中干扰?
BEM的威力不在命名本身,而在它迫使你把“状态”和“结构”分开思考:一个按钮的禁用态是业务逻辑决定的,它的图标是内部结构的一部分,二者不该混在一起靠!important强行缝合。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











