在前端开发中,CSS样式的命名没有统一标准时,很容易出现类名重复、样式互相覆盖的问题,尤其是在多人协作或者项目规模较大的场景下,这类问题会严重影响开发效率。BEM命名规范就是为了解决这类问题而诞生的,它是一套简单清晰的CSS类名命名约定,能让样式结构更清晰,降低维护成本。

BEM的核心概念
BEM是Block(块)、Element(元素)、Modifier(修饰符)三个英文单词的缩写,每个部分都有明确的含义:
- Block(块):指页面中独立存在的、可复用的组件,比如导航栏、按钮、卡片等,块之间相互独立,不会受到外部样式的影响。
- Element(元素):是块的组成部分,不能独立存在,必须依附于某个块,比如导航栏里的导航项、按钮里的图标都属于元素。
- Modifier(修饰符):用来表示块或者元素的状态、版本差异,比如按钮的禁用状态、卡片的不同尺寸等。
BEM的命名规则
BEM的命名采用双下划线、双破折号作为连接符,具体规则如下:
| 组成部分 | 命名格式 | 说明 |
|---|---|---|
| 块 | block-name | 块名使用小写字母,多个单词用单下划线连接 |
| 元素 | block-name__element-name | 块名和元素名之间用双下划线连接 |
| 修饰符 | block-name--modifier-name 或 block-name__element-name--modifier-name | 块或元素和修饰符之间用双破折号连接 |
BEM命名示例
下面以常见的卡片组件为例,展示BEM命名的实际用法:
<!-- 卡片块 --> <div class="card"> <!-- 卡片的标题元素 --> <h3 class="card__title">卡片标题</h3> <!-- 卡片的内容元素 --> <p class="card__content">卡片内容描述</p> <!-- 卡片的按钮元素,带尺寸修饰符 --> <button class="card__btn card__btn--large">查看详情</button> <!-- 卡片的按钮元素,带状态修饰符 --> <button class="card__btn card__btn--disabled">不可点击</button> </div>
对应的CSS样式代码如下:
/* 卡片块基础样式 */
.card {
padding: 16px;
border: 1px solid #eee;
border-radius: 8px;
}
/* 卡片标题元素样式 */
.card__title {
font-size: 18px;
margin-bottom: 8px;
}
/* 卡片内容元素样式 */
.card__content {
font-size: 14px;
color: #666;
margin-bottom: 16px;
}
/* 卡片按钮元素基础样式 */
.card__btn {
padding: 8px 16px;
border: none;
border-radius: 4px;
background-color: #409eff;
color: #fff;
cursor: pointer;
}
/* 大尺寸按钮修饰符样式 */
.card__btn--large {
padding: 12px 24px;
font-size: 16px;
}
/* 禁用状态按钮修饰符样式 */
.card__btn--disabled {
background-color: #ccc;
cursor: not-allowed;
}BEM的优势
使用BEM命名规范主要有以下几个好处:
- 类名语义化清晰,看到类名就能知道对应的组件结构,降低代码理解成本。
- 避免样式冲突,因为每个类名都和对应的块、元素绑定,不会出现全局样式污染的问题。
- 便于团队协作,统一的命名规则让不同开发者写出的代码风格一致,减少沟通成本。
- 可维护性强,修改某个组件的样式时,只需要找到对应的块、元素类名即可,不会影响其他组件。
注意事项
使用BEM时需要注意几个点:
- 不要嵌套过深,元素只需要和所属块直接关联,不需要体现层级关系,比如
card__title__icon这种命名是不符合规范的,应该写成card__title-icon。 - 修饰符需要和基础类名一起使用,不能单独使用,比如按钮禁用状态要写成
class="card__btn card__btn--disabled",而不是只写card__btn--disabled。 - 块要尽量保持独立,不要在块样式里依赖其他块的样式,这样才能保证块的复用性。