直接用 .header 或 .btn 会埋坑,因其未体现组件归属、层级与状态,导致协作中不敢修改、滥用 !important;应采用 BEM 三段式命名,如 .user-profile__btn--disabled,明确 Block、Element、Modifier 职责。

为什么直接用 .header 或 .btn 会埋坑
因为这些名字不说明“它在哪儿、属于谁、什么状态”,团队协作时,没人敢轻易改。比如一个 .btn 在登录页是蓝色,在弹窗里却是红色,但样式表里找不到上下文,最后只能加 !important 硬盖,越盖越乱。
真正的问题不是命名不够“高级”,而是没把组件的层级关系和功能边界写进类名里。
- 避免孤立命名:不写
.card,而写.user-profile__card—— 明确这是用户资料模块下的卡片 - 状态必须显式表达:禁用按钮不是
.btn--disabled,而是.user-profile__btn--disabled,防止跨模块误复用 - 修饰符(Modifier)只用于变体,不用于布局定位:用
.user-profile__avatar--large可以,但不用.user-profile__avatar--top-left(那是布局职责,该交给margin或grid-area)
BEM 的三段式怎么拆解才不僵硬
BEM 是 Block__Element--Modifier,但很多人卡在“哪个算 Block”——其实 Block 就是能独立存在、有明确语义的最小可复用单元,比如 search-form、product-list,而不是页面级的 homepage。
-
Block:名词,首字母小写,中划线分隔,如nav-menu、price-tag -
Element:必须依附于 Block,用双下划线连接,如nav-menu__item、price-tag__currency;不能嵌套,nav-menu__item__icon是错的 -
Modifier:用双短横,只描述状态或外观变体,如nav-menu__item--active、price-tag--on-sale;不写--mobile这类设备相关修饰符(响应式该用媒体查询)
示例:一个带图标的搜索框
.search-input {
/* Block 样式 */
}
.search-input__field {
/* Element,输入框本身 */
}
.search-input__icon {
/* Element,图标容器 */
}
.search-input--compact {
/* Modifier,紧凑模式 */
}
遇到嵌套组件时,BEM 怎么避免类名爆炸
真实项目里常有 user-card 里嵌 avatar 和 stats-bar,如果都按 BEM 展开,类名会变成 user-card__avatar__img —— 这违反了 BEM 原则,也失去语义。
- 每个 Block 应该自治:把
avatar单独抽成avatarBlock,user-card里只写<div class="user-card__avatar"><div class="avatar"></div></div> - 用 CSS 自定义属性承接共用视觉变量:比如
--avatar-size,让avatar和user-card__avatar共享尺寸逻辑,而非靠类名耦合 - 工具链辅助:PostCSS 插件
postcss-bem可自动校验嵌套层级,发现__后再出现__就报错
用 SCSS 写 BEM 时最常踩的三个坑
SCSS 的嵌套语法看着方便,但一不留神就把 BEM 写变形了,导致生成的 CSS 类名失效或冗余。
- 别用
&__element套多层:下面这段会生成错误的.card__header__title - 正确写法是每个 Block 单独写文件,用
@use引入,元素样式在各自文件里声明 - 禁止在 Modifier 中重写布局属性:比如
&--small { width: 50px; }没问题,但&--small { position: absolute; top: 0; }就越界了——这属于组件定位逻辑,该由父容器控制
反例(错误):
.card {
&__header {
&__title { /* 错!两层 __ */
font-weight: bold;
}
}
}
正例(正确):
.card {}
.card__header {}
.card__title {} /* 平级 Element,不嵌套 */
BEM 不是给机器看的,是给人读的。一旦发现要靠注释解释某个类名“其实是 XX 模块里的 YY 元素”,说明命名已经脱离语义,该重构了。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











