bem落地关键在于类名是否真实对应有封装边界的组件;block需能独立存在复用,element须直属block且不嵌套,modifier应标识状态归属而非容器约束。

直接在 class 属性里写 block__element--modifier 格式不是BEM落地的关键,关键在于你写的每个类名是否真实对应一个有封装边界的组件——写错名字,往往意味着DOM结构或职责划分本身就有问题。
怎么判断一个节点该是 Block 还是 Element
看它能不能脱离当前上下文独立存在、复用、测试。不是看它“长在哪儿”,而是看它“活不活得下去”。
- 如果
header__logo同时出现在footer和user-card里,那它就不是 header 的 element,而该是独立的logoblock -
div__title或section__content是典型错误:这些名字没业务含义,无法复用,也拦不住其他模块意外覆盖 - 按钮里的图标,若只服务该按钮(不暴露 props、不单独配色/尺寸),可叫
btn__icon;否则就是iconblock,比如icon--close
Element 名为什么不能嵌套,比如 card__content__title
BEM 不允许 __ 出现在 element 名里,因为 element 必须直属 block,且只表达一层从属关系。双下划线嵌套说明你把 DOM 结构层级当成了语义层级。
- ✅ 正确:
card__title、card__body、card__footer—— 全是card的直接子元素 - ❌ 错误:
card__content__title—— 这暗示content是 block,title是它的 element,但content本身只是个无逻辑的 wrapper - 解法:删掉无意义 wrapper,让
title直接挂card下;或真有复用需求,才把content提升为独立 block
btn--loading 和 btn__text--disabled 修饰符该加在哪儿
Modifier 描述的是「谁的状态变了」,不是「怎么变」。它不负责布局,也不传递容器信息,只开关样式或行为。
- ✅ 加在 Block 上:
btn--loading、input--error—— 整个组件进入某种状态 - ✅ 加在 Element 上:
menu__item--active、form__label--required—— 仅该部分表现不同 - ❌ 避免:
btn--in-modal、card--on-mobile—— 这类 modifier 实际是容器约束,应由父级 wrapper 类(如modal__content)或媒体查询处理 - ⚠️ 注意:
btn__text--disabled只在文本自身具备独立禁用语义时才合理;多数情况应由btn--disabled控制整体,并通过 CSS 单类选择器微调内部元素
最常被忽略的点是:BEM 类名不是字符串模板,而是组件边界的显式声明。你写 user-card__avatar__icon,问题不在语法报错,而在它悄悄破坏了 avatar 的封装性——一旦 avatar 要抽成独立组件,所有依赖这个嵌套名的地方都得重写。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











