双下划线__仅用于block与element之间,表示直属组成部分,非分隔符;单下划线或三层下划线均错误,元素不可嵌套,修饰符须用--紧接element且不可省略__。

双下划线 __ 只能出现在 block 和 element 之间
它不是“分隔符”而是语义标记,表示“这个 element 是该 block 的直属组成部分”。浏览器不校验,但写错会直接破坏 BEM 的可读性和协作一致性。
-
header__logo✅ 正确:logo 是 header 的固有子部分 -
header_logo❌ 错误:单下划线失去层级语义,被当成普通单词 -
header__nav__link❌ 错误:BEM 不允许元素嵌套,link 应是header__link或独立块nav__item -
user-card__avatar✅ 正确:block 名含连字符不影响 __ 使用
双连字符 -- 专用于 modifier,且必须紧贴前一部分
修饰符不单独存在,它必须依附于 block 或 element,用 -- 连接,不能省略前面的 __(如果修饰的是 element)。
-
button--disabled✅ 修饰 block -
menu__item--active✅ 修饰 element,__item不可省略 -
menu__item-active❌ 错误:少一个-,变成item-active,语义模糊 -
button__icon--large✅ 元素级修饰符,结构完整
连字符 - 只用于拼接多词的 block / element / modifier 名称
它纯粹是单词连接符,和层级无关。出现在 block 名里(如 user-card)、element 名里(如 search-form__input)、modifier 名里(如 --is-hidden)都合法。
-
form-control__error-message✅ element 名含连字符,没问题 -
btn--primary-large✅ modifier 名含连字符,表示复合状态 -
dialog__ok-btn✅ element 名用-连接,不是层级符号 -
dialog__ok--btn❌ 错误:把--插进 element 名,混淆了 modifier 位置
动态生成类名时最容易踩的坑
Vue/React 中用模板字符串拼接 ${block}__${el},一旦 el 来自 props 且含空格、大写或非法字符,就会产出无效类名,比如 user-card__first name。
- 推荐用
bem-cn或@bem-react/classname工具自动 sanitize 和拼接 - 手动拼接前务必 normalize:转小写、去空格、替换非法字符为
- - 避免在 element 名里塞位置信息(如
sidebar__top-nav),应拆成sidebar__nav+--position-top
BEM 的连接符不是风格偏好,是语义契约。__ 和 -- 写错一字符,类名就脱离规范,后续维护、工具链识别、团队对齐都会出问题——尤其当组件被复用到新项目时,错误命名会像幽灵一样持续冒泡。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











