🧩 前端命名规范之 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 个问题:
- 谁是 Block? → 独立、可复用的最外层容器(如
.article、.nav、.user-card)。 - 谁是 Element? → 属于这个容器、不能独立存在的子部分(如
__title、__link、__avatar)。 - 谁是 Modifier? → 用来描述"变体"或"状态"的(如
--active、--highlight、--vip)。
⚠️ 关键原则:Modifier 只改样式(颜色、大小、显隐),不改 HTML 结构。文本也一样,加粗、变色、缩进,统统用 Modifier 搞定。
⚠️ 使用注意事项
- Block 必须独立:Block 不应依赖父级或全局样式。
- Element 必须隶属于 Block:不能脱离 Block 单独使用。
- Modifier 用于变化 :Modifier 只负责样式差异,不改变结构。
- 避免过度嵌套:BEM 不关注 DOM 层级,只关注逻辑层级。
- 不要使用标签选择器:一律用类名,保证可复用性。
🛠 适用场景与不适用场景
| ✅ 适用场景 | ❌ 不适用场景 |
|---|---|
| 大型多人协作项目 | 简单的静态页面 |
| 组件化开发(Vue / React) | 快速原型开发 |
| 长期维护的中后台系统 | 纯内容型官网(少量样式) |
📖 总结
- BEM 的核心思想是 Block → Element → Modifier
- 命名格式统一为:
block__element--modifier - 优势:语义清晰、样式隔离、便于维护
- 推荐结合 SCSS / Less 使用,通过嵌套语法简化编写
💡 BEM 不是银弹,但它是一套成熟、轻量、无侵入的 CSS 组织方案。
掌握它,是迈向工程化 CSS 的重要一步。
📌 相关扩展:
- BEM 官方文档
- CSS Modules / Tailwind CSS 对比分析
- 大型项目 CSS 架构设计最佳实践