前端命名规范之 BEM 入门与实践

🧩 前端命名规范之 BEM 入门与实践

让 CSS 类名更有语义、更易维护 ------ BEM 命名方法论详解

📌 为什么需要 BEM?

在传统 CSS 开发中,随着项目体积增大,类名冲突、样式覆盖、维护困难等问题逐渐暴露。

BEM (Block Element Modifier)应运而生,它是一种组件化的 CSS 命名方法论 ,旨在提高代码的可读性可维护性可扩展性


🧱 BEM 核心概念

BEM 将 UI 划分为三个层级:

层级 含义 示例
Block 独立、可复用的组件(容器) .header, .menu, .button
Element Block 的子元素,依赖于 Block .menu__item, .button__icon
Modifier 改变 Block / Element 的外观或状态 .button--primary, .menu__item--active

✍️ 命名语法规则

BEM 使用以下命名约定:

  • Block.block
  • Element.block__element(双下划线 __
  • Modifier.block--modifier.block__element--modifier(双连字符 --

✅ 正确示例

html 复制代码
<!-- Block: search-form -->
<form class="search-form">
  <!-- Element -->
  <input class="search-form__input" />
  <!-- Element + Modifier -->
  <button class="search-form__button search-form__button--primary">
    搜索
  </button>
</form>
css 复制代码
.search-form { /* ... */ }
.search-form__input { /* ... */ }
.search-form__button { /* ... */ }
.search-form__button--primary { /* ... */ }

🔄 常见变体写法

在实际项目中,BEM 也有几种常见的变体风格,可根据团队规范选择:

风格 示例
经典 BEM(双下划线 + 双连字符) .block__element--modifier
下划线风格 .block_element_modifier
驼峰组合风格 .block__element-modifier

📌 推荐使用经典双下划线 + 双连字符,视觉区分度最高,IDE 智能提示也更友好。


🧩 多场景实战:从文本到导航,BEM 怎么拆?

BEM 的核心不是"长得像卡片",而是逻辑拆分。不管外观是文字、图片还是按钮,都按"独立容器(Block)→ 组成部分(Element)→ 状态变化(Modifier)"三步走。


场景一:文章内容块(纯文本 / 富文本样式)

html 复制代码
<article class="article">
  <h1 class="article__title">深入理解 BEM 规范</h1>
  <div class="article__meta">
    <span class="article__author">作者:张三</span>
    <span class="article__date">2026-07-02</span>
  </div>
  <div class="article__body">
    <p class="article__paragraph article__paragraph--first">
      首段特殊缩进,不需要首行缩进。
    </p>
    <p class="article__paragraph">
      普通正文段落,字体大小 16px,行高 1.8。
    </p>
    <blockquote class="article__quote">
      引用文本:这里是引用的内容。
    </blockquote>
    <p class="article__paragraph article__paragraph--highlight">
      这段文字有高亮背景色(Modifier 控制样式变化)。
    </p>
  </div>
</article>
css 复制代码
.article {
  max-width: 800px;
  padding: 20px;
  background: #fafafa;
}
.article__title {
  font-size: 28px;
  font-weight: bold;
  color: #333;
}
.article__meta {
  color: #999;
  font-size: 14px;
  border-bottom: 1px solid #eee;
  padding-bottom: 10px;
}
.article__paragraph {
  font-size: 16px;
  line-height: 1.8;
  color: #444;
}
.article__paragraph--first {
  text-indent: 2em;
}
.article__paragraph--highlight {
  background: #fff3cd;
  padding: 8px 12px;
  border-radius: 4px;
}
.article__quote {
  border-left: 4px solid #409EFF;
  padding-left: 16px;
  color: #666;
  font-style: italic;
}

✅ 即使是纯文本,article__paragraph--highlight 也是 Modifier,因为它只负责"改变这一段的外观"。


场景二:导航菜单(结构 + 激活状态)

html 复制代码
<nav class="nav">
  <ul class="nav__list">
    <li class="nav__item">
      <a class="nav__link nav__link--active">首页</a>
    </li>
    <li class="nav__item">
      <a class="nav__link">产品中心</a>
    </li>
    <li class="nav__item">
      <a class="nav__link nav__link--disabled">关于我们(暂不可用)</a>
    </li>
  </ul>
</nav>
css 复制代码
.nav {
  background: #2c3e50;
  padding: 0 20px;
}
.nav__list {
  list-style: none;
  display: flex;
  gap: 0;
  margin: 0;
  padding: 0;
}
.nav__item {
  padding: 12px 20px;
}
.nav__link {
  color: #fff;
  text-decoration: none;
  font-size: 16px;
  padding: 4px 0;
  border-bottom: 2px solid transparent;
  transition: 0.3s;
}
.nav__link--active {
  border-bottom-color: #409EFF;
  color: #409EFF;
}
.nav__link--disabled {
  color: #666;
  cursor: not-allowed;
  pointer-events: none;
}

场景三:用户信息标签(带 VIP 角标)

html 复制代码
<div class="user-card">
  <img class="user-card__avatar" src="avatar.jpg" alt="头像" />
  <div class="user-card__info">
    <span class="user-card__name">王小二</span>
    <span class="user-card__tag user-card__tag--vip">VIP</span>
    <span class="user-card__tag user-card__tag--new">新用户</span>
  </div>
  <button class="user-card__btn user-card__btn--follow">+ 关注</button>
</div>
css 复制代码
.user-card {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 16px;
  border: 1px solid #e4e7ed;
  border-radius: 8px;
}
.user-card__avatar {
  width: 48px;
  height: 48px;
  border-radius: 50%;
}
.user-card__name {
  font-size: 16px;
  font-weight: 600;
}
.user-card__tag {
  font-size: 12px;
  padding: 2px 8px;
  border-radius: 12px;
  background: #f0f0f0;
  color: #666;
}
.user-card__tag--vip {
  background: #ffd700;
  color: #b8860b;
}
.user-card__tag--new {
  background: #409EFF;
  color: #fff;
}
.user-card__btn--follow {
  background: #409EFF;
  color: #fff;
  border: none;
  padding: 6px 16px;
  border-radius: 4px;
  cursor: pointer;
}

📐 拆解心法(记住这三问)

无论遇到什么 UI,问自己 3 个问题:

  1. 谁是 Block? → 独立、可复用的最外层容器(如 .article.nav.user-card)。
  2. 谁是 Element? → 属于这个容器、不能独立存在的子部分(如 __title__link__avatar)。
  3. 谁是 Modifier? → 用来描述"变体"或"状态"的(如 --active--highlight--vip)。

⚠️ 关键原则:Modifier 只改样式(颜色、大小、显隐),不改 HTML 结构。文本也一样,加粗、变色、缩进,统统用 Modifier 搞定。


⚠️ 使用注意事项

  1. Block 必须独立:Block 不应依赖父级或全局样式。
  2. Element 必须隶属于 Block:不能脱离 Block 单独使用。
  3. Modifier 用于变化 :Modifier 只负责样式差异,不改变结构。
  4. 避免过度嵌套:BEM 不关注 DOM 层级,只关注逻辑层级。
  5. 不要使用标签选择器:一律用类名,保证可复用性。

🛠 适用场景与不适用场景

✅ 适用场景 ❌ 不适用场景
大型多人协作项目 简单的静态页面
组件化开发(Vue / React) 快速原型开发
长期维护的中后台系统 纯内容型官网(少量样式)

📖 总结

  • BEM 的核心思想是 Block → Element → Modifier
  • 命名格式统一为:block__element--modifier
  • 优势:语义清晰、样式隔离、便于维护
  • 推荐结合 SCSS / Less 使用,通过嵌套语法简化编写

💡 BEM 不是银弹,但它是一套成熟、轻量、无侵入的 CSS 组织方案。

掌握它,是迈向工程化 CSS 的重要一步。


📌 相关扩展:

  • BEM 官方文档
  • CSS Modules / Tailwind CSS 对比分析
  • 大型项目 CSS 架构设计最佳实践