直接写 .button 会导致样式污染和复用困难,因其缺乏作用域隔离,易引发类名冲突、覆盖混乱及结构耦合;BEM 要求严格命名、单类规则、直系子节点语义和完整样式定义以保障复用性。

为什么直接写 .button 会导致样式污染和复用困难
当你在多个页面都用 .button 表示按钮,但实际需要「主按钮」「次按钮」「禁用态」「小尺寸」等变体时,很容易演变成这样:
.button { /* 基础样式 */ }
.button--primary { /* 覆盖色值 */ }
.button.is-disabled { /* 又混用了 BEM 和状态类 */ }
.header .button { /* 靠父选择器强行限定作用域 */ }问题在于:这些规则彼此耦合、无法独立复用、难以预测覆盖顺序。BEM 的核心不是“多写横线”,而是用命名约束作用域边界。
block__element--modifier 命名必须严格对应 DOM 结构
BEM 不是字符串拼接游戏,__element 必须是 block 的**直系子节点**,--modifier 必须只用于开关状态或外观变体,且不改变结构语义。
- ✅ 正确:
<div class="card"><h3 class="card__title"></h3></div>——card__title是card的子元素 - ❌ 错误:
<div class="card"><div class="card__content"><p class="card__title"></p></div></div>——p不是card直系子节点,card__title语义断裂 - ✅ 修饰符用法:
card--featured、button--small;禁止:card--has-title(这是结构判断,应由 JS 控制类存在与否)
避免嵌套 CSS 选择器,所有样式必须单 class 规则
BEM 的样式复用能力完全依赖“一个 class 对应一套完整样式”。一旦写 .card .card__title,就等于放弃 BEM 的隔离性优势。
立即学习“前端免费学习笔记(深入)”;
- ❌ 禁止:
.card .card__title { font-size: 1.2em; }—— 依赖层级,无法单独使用card__title - ✅ 正确:
.card__title { font-size: 1.2em; margin: 0; }—— 它必须定义完整排版,不假设父容器 - ⚠️ 注意:
card__title的样式不能靠card的font-family继承来省略,必须显式声明,否则脱离上下文就失效
如何让 BEM 真正支持跨项目复用
光有命名不够。真正可复用的 BEM 模块,需要满足三个硬条件:
- 所有
__element和--modifier类名都在同一份文档中明确定义,不靠“约定俗成” - CSS 文件不包含任何全局重置(如
h1 { margin: 0; }),所有样式仅响应自身 class - 提供最小 HTML 结构示例(例如:
<div class="button button--primary">提交</div>),并注明哪些 class 可组合、哪些互斥 - 如果模块含 JS 行为(如
button--loading),必须同步暴露状态切换方法,而非让用户自己el.classList.add()
没做到这四点,所谓的“BEM 组件”只是换了个名字的重复代码。


















