BEM不是必须的,但项目组件超5个或出现样式冲突时即成止损刚需;__和--不可替换为-,因前者明确表达“所属关系”与“状态变体”,保障选择器可预测、工具可自动化,避免语义误判与全局污染。

直接说结论:BEM不是必须的,但一旦项目组件超过5个、团队协作开始出现样式冲突,bem 就从“可选规范”变成“止损刚需”。它解决的从来不是“怎么写类名”,而是“谁改了什么样式、为什么改、会不会影响别人”。
为什么 block__element--modifier 不能写成 block-element-modifier
这不是语法洁癖,是CSS选择器解析逻辑决定的。浏览器匹配 .header__logo--large 时,会按完整字符串查找;而 .header-logo-large 在多人协作中极易被误判为“独立组件”,比如有人加了 .logo-large 规则,实际覆盖了所有带 logo-large 的元素——根本没意识到它本该只属于 header 块。
-
__是明确的“属于”分隔符,表示logo是header的子元素,语义不可拆解 -
--是明确的“状态/变体”标识,--hover和--disabled属于同一维度,不会和元素名混淆 - 连字符
-在 BEM 中只用于单词内连接(如user-profile),不承担结构含义,混用会导致正则提取、自动化工具(如postcss-bem)失效
如何避免 block__element__subelement 这种嵌套地狱
BEM 明确反对三层及以上的下划线嵌套。出现 card__content__title,说明你已经把“内容区”当成了独立 block,应该拆成 card + card-content 两个平行 block,或把 title 提升为 card__title ——只要它在视觉和语义上是 card 的一级组成部分。
- 判断标准不是 DOM 深度,而是“能否独立存在”:如果
content拿出来能单独复用,它就该是card-contentblock - 真实项目中,90% 的“深层嵌套”源于过早抽象,先写
card__title、card__meta、card__footer,等真有多个“内容卡片”再抽card-content - 工具链里可以用
stylelint-selector-bem-pattern配置规则,自动拦截__出现两次的类名
Modifier 必须是布尔值或有限枚举,不能是具体样式值
写 button--width-200px 或 input--color-red 是典型反模式。Modifier 描述的是“意图”,不是“结果”。--wide 可以对应 200px,也可以在响应式中变成 100%;--danger 可以控制颜色、边框、光标,甚至 aria-label。
- 允许:
button--primary、button--loading、modal--fullscreen - 禁止:
button--bg-blue、text--fs-14px、icon--size-24 - 真正需要动态尺寸?用 CSS 自定义属性:
button--large { --button-height: 48px; },然后在基础button里用height: var(--button-height);
BEM 最容易被忽略的点,其实是 modifier 的组合使用限制:多个 modifier 同时存在时,必须能正交共存。比如 button--primary--loading 合理,但 button--primary--secondary 就自相矛盾——这说明你的 modifier 设计没对齐业务语义,得回退一步重新梳理状态机。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











