CSS BEM命名约定是一种前端开发中广泛使用的CSS类名命名规范,它通过明确的命名规则让CSS代码结构更清晰,有效避免样式冲突问题,提升项目的可维护性。

什么是CSS BEM命名约定
BEM是Block(块)、Element(元素)、Modifier(修饰符)三个单词的缩写,是一种用于前端开发的命名方法论,核心思想是将页面拆分成独立的、可复用的组件,通过统一的命名规则描述组件的结构与状态。
- Block(块):指页面中独立、可复用的功能单元,比如导航栏、卡片、按钮等,块名需要语义化,描述组件的功能。
- Element(元素):是块的组成部分,不能独立存在,只能在块的上下文里使用,描述组件内部的子部分。
- Modifier(修饰符):用来描述块或者元素的状态、版本、样式变体,比如禁用状态、大尺寸版本等。
为什么CSS BEM命名约定很重要
在没有统一命名规范的项目中,开发者往往会随意给元素起类名,比如直接使用red-text、left-box这类描述样式或位置的类名,后续样式调整时就需要同时修改HTML和CSS,维护成本很高。而BEM命名约定能带来这些好处:
- 避免样式冲突:所有类名都带有明确的组件前缀,不会和全局样式或者其他组件的样式产生冲突。
- 提升可读性:看到类名就能直接知道这个元素属于哪个组件,是组件的哪部分,处于什么状态。
- 增强可复用性:每个块都是独立的结构,可以直接复用到其他页面或者项目中,不需要修改类名和样式。
- 方便团队协作:统一的命名规则让团队所有成员的代码风格保持一致,新人接手项目时能更快理解代码结构。
如何使用CSS BEM命名约定
基础命名规则
BEM有固定的命名格式,不同部分的连接符有明确要求:
- 块名:直接写语义化的名称,比如
card、nav、button。 - 块和元素连接:使用双下划线
__,格式为块名__元素名,比如card__title表示卡片组件的标题元素。 - 块或元素和修饰符连接:使用双横杠
--,格式为块名--修饰符名或者块名__元素名--修饰符名,比如button--disabled表示禁用状态的按钮,card__title--large表示大尺寸的卡片标题。
实际使用示例
下面以一个简单的卡片组件为例,展示BEM命名的完整使用方式。
首先是HTML结构,按照BEM规则给元素添加类名:
<!-- 卡片块 -->
<div class="card">
<!-- 卡片的标题元素 -->
<h3 class="card__title">卡片标题</h3>
<!-- 卡片的内容元素 -->
<p class="card__content">这是卡片的内容描述部分</p>
<!-- 卡片的操作区域元素 -->
<div class="card__actions">
<!-- 按钮块,带primary修饰符 -->
<button class="button button--primary">确认</button>
<!-- 按钮块,带disabled修饰符 -->
<button class="button button--disabled">取消</button>
</div>
</div>
对应的CSS样式写法如下,所有样式都基于BEM类名定义,避免全局污染:
/* 卡片块的基础样式 */
.card {
padding: 20px;
border: 1px solid #e5e5e5;
border-radius: 8px;
max-width: 300px;
}
/* 卡片的标题元素样式 */
.card__title {
font-size: 18px;
font-weight: bold;
margin-bottom: 10px;
}
/* 卡片的内容元素样式 */
.card__content {
font-size: 14px;
color: #666;
line-height: 1.5;
margin-bottom: 20px;
}
/* 卡片的操作区域元素样式 */
.card__actions {
display: flex;
gap: 10px;
}
/* 按钮块的基础样式 */
.button {
padding: 8px 16px;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
}
/* 按钮的primary修饰符样式 */
.button--primary {
background-color: #1890ff;
color: #fff;
}
/* 按钮的disabled修饰符样式 */
.button--disabled {
background-color: #d9d9d9;
color: #999;
cursor: not-allowed;
}
使用注意事项
- 不要嵌套过深:BEM的类名本身已经描述了层级关系,不需要在CSS里写多层嵌套选择器,比如不要写
.card .card__title,直接写.card__title即可。 - 修饰符不要单独使用:修饰符必须依附于块或者元素存在,不能单独给一个元素只加修饰符类名,比如不能只写
class="--disabled",必须写成class="button button--disabled"。 - 避免滥用BEM:并不是所有元素都需要用BEM命名,比如页面级的唯一元素或者没有复用需求的简单结构,可以适当简化命名,不要为了遵循规范而增加不必要的复杂度。
常见问题解答
如果元素层级很深怎么办
如果组件内部的元素层级超过两层,比如card__content__item这种结构,说明组件拆分不合理,应该把这个深层元素拆分成独立的块,而不是无限制地增加下划线层级。
BEM和CSS预处理器可以一起使用吗
完全可以,BEM是命名规范,和使用的CSS写法无关。比如使用Sass的时候,可以用父选择器&来简化BEM类名的书写:
.card {
padding: 20px;
border: 1px solid #e5e5e5;
&__title {
font-size: 18px;
font-weight: bold;
}
&__content {
font-size: 14px;
color: #666;
}
}
这种写法编译后的CSS依然符合BEM命名规则,同时减少了重复书写块名的工作量。