架构-css-bem

系统且详细地讲解 BEM 架构:从背景、核心思想、命名规则、使用方法、优缺点,到实际项目中的最佳实践。

一、BEM 是什么?

BEM 是 Block(块)、Element(元素)、Modifier(修饰符)的缩写,是一种前端 CSS 命名方法论,用于让你的 CSS:

  1. 更清晰(语义清楚)
  2. 更模块化(组件独立)
  3. 更易维护(避免样式冲突)

BEM 最早由俄罗斯的 Yandex 公司提出,用于构建大型的、可维护的用户界面。


二、为什么需要 BEM?

传统 CSS 存在以下问题:

  1. 样式难以复用,组件耦合严重
  2. 命名混乱、容易冲突(比如 .title 在很多组件里都有)
  3. 样式覆盖混乱(选择器优先级、继承乱套)

BEM 的出现就是为了解决这些问题,通过结构化命名组件式思维来组织样式。


三、BEM 的核心概念详解

1. Block(块)

  • 描述一个独立功能的组件或模块
  • 可以单独使用,具有自己的语义、样式。
  • 示例:menuformbuttonheadermodal
1
<div class="menu"></div>

2. Element(元素)

  • 是 Block 的一部分,不能独立使用
  • 它是 block 的逻辑子项,用双下划线 __ 连接。
  • 示例:menu__itemform__labelmodal__close-button
1
2
3
<div class="menu">
<div class="menu__item">菜单项</div>
</div>

3. Modifier(修饰符)

  • 描述一个 Block 或 Element 的状态或外观变化
  • 用双中划线 -- 表示。
  • 可以是布尔(如 --active)或取值型(如 --size-large)。
1
2
<div class="button button--primary"></div>
<div class="menu__item menu__item--active"></div>

四、BEM 命名规则总结

类型示例含义
Block.form模块名称
Element.form__input模块内的子元素
Modifier.form--dark.form__input--error修饰模块或元素的样式或状态

五、BEM 示例完整代码

HTML 示例

1
2
3
4
5
6
7
8
9
10
11
12
13
<!-- Block: card -->
<div class="card card--featured">

<!-- Element: card__title -->
<h2 class="card__title">标题</h2>

<!-- Element: card__description -->
<p class="card__description">卡片内容简介</p>

<!-- Element + Modifier -->
<button class="card__button card__button--primary">确认</button>

</div>

SCSS 示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
.card {
padding: 16px;
border: 1px solid #ccc;
background-color: white;

&--featured {
background-color: #fdf5e6;
border-color: orange;
}

&__title {
font-size: 1.5rem;
}

&__description {
color: #666;
}

&__button {
padding: 8px 12px;
border: none;

&--primary {
background-color: blue;
color: white;
}
}
}

六、BEM 的优点

优点说明
清晰的结构一眼能看出这个类来自哪个组件、是哪个部分
模块化每个组件封闭,不容易产生样式污染
易于维护项目大了也能按组件快速查找
易复用Block 可以复用,Modifier 可以扩展样式
减少冲突彻底避免 .title.btn 类的全局冲突问题

七、常见误区

错误写法正确写法原因
.header-title.header__title缺少结构层级,语义不清
.btn__hover.btn--hover状态用 Modifier 实现
.modal__footer__buttonmodal-footer__button不建议多层元素嵌套,建议抽出新 Block

八、BEM 在真实项目中的实践建议

推荐搭配

  • SCSS / Less 的嵌套功能
  • 组件化框架(如 Vue、React、Svelte)搭配 CSS Module
  • 使用 linter 或命名规则插件(如 stylelint)

文件结构建议

1
2
3
4
bash复制编辑components/
└── card/
├── Card.svelte
└── card.scss

组件命名建议

  • 文件名、组件名用小写连字符(如 card-title.svelte
  • 样式类使用 BEM 命名(如 card__title

九、BEM 与其他命名法对比

命名法特点推荐场景
BEM结构清晰、样式独立、可维护中大型组件项目
OOCSS基于对象复用性样式复用需求高
SMACSS按功能分类样式灵活分类项目
Atomic CSS原子化类名(如 Tailwind)函数式写法项目

十、总结 BEM

“BEM 让你的 CSS 组件化、结构化、不打架。”