ID选择器CSS权重为100,易致样式冲突和!important滥用;应仅用于JS锚点或语义标识,样式全部交由BEM类名控制,禁用ID参与CSS匹配。

ID选择器在CSS中权重为100,远超类名(10)和标签(1),一旦混用,很容易触发!important硬覆盖或样式打架,根本原因不是“写错了”,而是ID天然不具备复用性,也不该承担样式职责。
为什么ID选择器会让CSS权重失控
浏览器计算选择器特异性时,#header 单独出现就占100分,而 .header__title 才10分。这意味着:哪怕你只在局部改一个颜色,只要上级用了ID,你就得用!important或再套一层ID才能覆盖——这不是调优,是恶性循环。
- 常见错误现象:
#user-modal .btn--primary这种组合,权重高达110,后续任何基于类名的扩展(比如.btn--primary--loading)都压不过它 - ID本意是JS锚点或语义标识(如
aria-labelledby),不是样式钩子;把它当class用,等于把DOM结构强耦合进样式层 - 当页面引入第三方组件(如
el-dialog),它们内部可能也用ID做控制,冲突几乎必然发生
如何用BEM彻底移除ID选择器
BEM不禁止ID存在,但要求它只出现在HTML属性里,不参与CSS匹配。所有样式必须由class驱动,且命名自带作用域。
- 把原写法
#profile-card .avatar img改成.profile-card__avatar,对应HTML中显式加类:<img class="profile-card__avatar"> - JS需要定位时,用
document.querySelector('.profile-card__avatar')代替document.getElementById('avatar-img')——类名足够唯一,且不污染样式权重 - 如果必须保留ID(如服务端渲染需锚点),确保它和class共存但分离:
<div id="main-content" class="layout__main">,CSS里只认<code>.layout__mainBEM类名怎么写才不会意外拉高权重
权重问题常藏在“看起来很合理”的嵌套里。BEM本身不保权重低,关键是你怎么用。
- 禁止写
.card .card__title—— 这是两个类选择器叠加,权重20;正确写法只有.card__title,单独一条规则 - 避免用标签限定:
h3.card__title权重是11(标签1 + 类10),而.card__title就是10;BEM约定所有样式绑定类名,不依赖标签类型 - 修饰符不要叠用:
.button--primary.button--large权重20,应合并为.button--primary--large或拆成独立规则(.button--primary+.button--large)
真正难的不是命名规则,而是团队敢不敢删掉那行
#sidebar-nav。一旦ID从CSS里消失,后续所有组件迁移、主题切换、状态管理都会少掉一层隐性约束——这个转折点往往发生在第一次有人把getElementById改成querySelector的时候。 - 禁止写











