BEM 命名规范

BEM 是一种通过 Block、Element、Modifier 命名约定模拟局部作用域的 CSS 组织方法,用来降低全局类名冲突和协作成本。

#type / concept #status / growing #tech / dev / frontend #resource / css #resource / bem

[!info] related notes

BEM 命名规范

一句话定义

BEM 是一种 CSS 命名规范,通过 BlockElementModifier 把类名写成稳定的结构化名字,以在全局命名空间里人工制造“局部边界”。

核心机制 / 工作原理

BEM 的核心不是工具,而是约定。

它默认把一个 UI 单元拆成三层:

  • Block:独立存在的组件或模块
  • Element:Block 内部组成部分
  • Modifier:状态、尺寸、主题或变体

常见写法:

.card {}
.card__title {}
.card__footer {}
.card--featured {}
.card__title--muted {}

它试图解决的是全局 CSS 的命名冲突问题。

如果不用 BEM,项目里很容易同时出现很多 .title.button.content。 用了 BEM 后,类名会被拉回具体语境里,例如:

.product-card__title {}
.user-profile__title {}
.article-preview__title {}

这样虽然仍然是全局 CSS,但冲突概率会显著下降。

从本质上说,BEM 是在 CSS 缺少模块机制时,用命名约定补足模块边界。

最小例子 / 最小场景

<article class="card card--featured">
  <h2 class="card__title">标题</h2>
  <div class="card__content">内容</div>
  <footer class="card__footer">尾部</footer>
</article>
.card {
  padding: 16px;
  border-radius: 8px;
}

.card__title {
  font-size: 20px;
}

.card--featured {
  border: 2px solid #1677ff;
}

阅读 .card__title 时,可以直接知道它属于 card,不会把它误判成全局公共类。

边界与易混淆点

  • BEM 解决的是命名冲突和协作可读性,不是硬性的样式隔离。
  • 如果有人直接写 .button {},工具并不会阻止全局污染,所以它依赖团队纪律和 code review。
  • 类名可能变得很长,书写成本和视觉噪音会增加。
  • BEM 和 Sass、CSS Modules 并不冲突。
    • 在全局 CSS 时代,BEM 常作为主要隔离手段。
    • 在 CSS Modules 时代,BEM 仍可作为组件内部的命名语言。
  • BEM 更适合原生 CSS、传统多页面项目、或不想强依赖复杂样式运行时的团队。
创建于 2026/5/14 更新于 2026/5/27