BEM命名中block是独立功能模块(如header)、element是其不可拆分的子组件(如card__title)、modifier描述状态或变体(如card--featured);核心是不依赖DOM层级,通过显式类名实现高解耦与可维护性。

什么是BEM命名里的block、element和modifier
BEM不是语法,是命名约定:一个block代表独立功能模块(如header、card),element是它内部不可拆分的子组件(如card__title、card__image),modifier描述状态或变体(如card--featured、button--disabled)。关键在“不依赖层级”——card__title的样式不靠.card h2这种后代选择器,而是直接命中类名。
为什么.card__title比.card h2更解耦
用后代选择器会隐式绑定DOM结构:一旦把h2换成div,样式就失效;还可能被外层样式污染(比如全局h2 { margin: 0 } 意外覆盖)。而BEM强制显式声明关系:
-
card__title只响应自己这个类,不管标签类型、父容器、兄弟节点 - 修改DOM结构时,只需同步更新class名,无需动CSS
- 多个
card实例可共用同一套CSS,不因嵌套深度不同产生权重冲突
--和__写错会导致什么问题
拼写错误不会报错,但会让选择器完全失效。常见手误:
- 写成
card__title--large(混用__和--)→ 应为card__title--large或card--large,前者修饰元素,后者修饰块 - 漏掉下划线:
card_title→ 浏览器当普通类名,BEM工具链(如postcss-bem)无法识别 - 大小写混用:
Card__Title→ CSS类名区分大小写,HTML里写card__title就匹配不上
建议用编辑器插件(如VS Code的BEM Tools)实时校验命名格式。
修饰符要不要加block类名一起用
要。单独用card--featured没问题,但card__title--large必须和card__title共存,否则语义断裂。实际写法是:
<div class="card card--featured"> <h3 class="card__title card__title--large">标题</h3> </div>
原因:BEM中modifier是“增强”,不是“替代”。去掉基础类名,就失去了它所属的element上下文,CSS里.card__title--large规则可能被误用于其他场景(比如有人复制代码时只抄了修饰符类)。
真正容易被忽略的是:团队协作时,有人会为了“减少class数量”省略基础类,结果调试时发现样式不生效,却查半天DOM结构——其实只是少写了一个card__title。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











