bem类名本身不改变权重,但能帮你避开高权重陷阱,因为它强制只用单类名(如.btn、.btn--primary),权重恒为0,1,0,杜绝id、标签、后代选择器等导致权重飙升的写法,从源头规避1,1,2等高权重组合。

为什么BEM类名本身不改变权重,但能帮你避开高权重陷阱
BEM不是权重计算器,.btn--primary和.btn权重都是0,1,0,它真正起作用的是约束写法:不让你写出#header .nav li a这种1,1,2权重的选择器。ID选择器一个就顶100个类,后代选择器每多一层标签就+0,0,1,而BEM强制你只用单类名,天然卡死在0,1,0。
哪些写法会偷偷抬高BEM选择器权重
常见错误是“披着BEM皮,干着嵌套事”:
-
.card .card__title→ 权重变成0,2,0,破坏BEM初衷 -
button.card__button→ 标签+类组合,权重0,1,1 -
.card__title:hover→ 伪类本身不增权重,但若写成.card:hover .card__title,立刻变成0,2,0 - 混用
!important或内联style → 直接跳过权重计算,但会让覆盖逻辑失控
怎么验证你的BEM选择器真没抬权
别信文件名或注释,看浏览器里最终生效的规则:
- 打开DevTools → Elements → 选中元素 → Computed → Styles → 点开对应CSS规则,确认选择器是纯类名(如
.form__input),不含空格、>、+或标签名 - Linux/macOS下快速扫描:
grep -r "\.[a-z]\+ \.[a-z]" src/css/,揪出所有带空格的选择器 - CI中接入
stylelint-selector-bem-pattern,拦截.modal .modal__close这类退化写法
遇到第三方库强塞高权重怎么办
antd、Bootstrap这些库常用!important或ID选择器,BEM救不了它们,但能让你的覆盖更干净:
- 不用
!important硬怼,改用相同权重的BEM修饰符:.my-button--disabledvs.ant-btn-disabled - 把第三方组件包进自己的block里,用scoped或CSS Modules隔离作用域,避免全局污染
- 状态切换交给JS控制类名:
el.classList.toggle('card--loading'),而不是依赖:is(.card:has([data-loading]))这类高成本伪类
0,1,0。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











