bem禁止三段式类名如card__header__title,因其违反block__element和block--modifier规则,导致语义断裂、样式失效、复用困难及调试不便;应依复用性拆为独立block、modifier、state类或data-context。

直接删掉三段式类名,比如 card__header__title 或 nav__item__dropdown——这不是写法问题,是语义断裂的信号。
为什么 card__header__title 是非法命名
BEM 只允许 block__element 和 block--modifier 两种结构。card__header__title 实际在声明 “header 是一个 block”,但它只是 card 的一个 element,不能承载子 element。这种写法会让样式静默失效:
- 改个 DOM 包裹层(比如给
card__header加个<div class="wrapper">),<code>card__header__title就完全不生效 - 无法单独抽离复用:你没法把
card__header__title拿到用户资料页去用,它被当前 HTML 路径锁死了 - DevTools 里搜
title找不到对应样式,因为类名是拼出来的,不是语义化的 - 会复用 → 提为独立 Block:
heading、dropdown、list,各自带__item、__menu - 几乎不复用,但强依赖容器 → 用 Modifier:
heading--in-card-header,而不是card__header__title - 一次性弱复用场景(如折叠面板里的二级标题)→ 用 State 类:
class="heading is-subheading" - 样式高度依赖容器又不想污染命名 → 用
data-context:<div data-context="modal"><button class="button">,对应 CSS:<code>[data-context="modal"] .buttonHTML 嵌套深,但类名不能跟着“滑动”
DOM 可以保持四层甚至五层嵌套,关键在于类名归属是否清晰。BEM 不要求 HTML 扁平化,只要求类名不随 DOM 层级“滑动”。
- 正确写法:
<div class="card"><div class="card__body"><div class="table"><div class="table__row"><div class="table__cell"> <li>错误写法:<code><div class="card"><div class="card__body"><div class="card__body__table"><div class="card__body__table__row"> <li>微调布局(如上下间距、颜色)靠父级类名控制:<code>.card__body .heading { margin-bottom: 8px; },这种 CSS 嵌套仅限一层,且只用于布局微调,不定义核心样式 - 禁止在 SCSS/Less 中写
&__header { &__title { } }—— 它会编译出非法类名,还容易误给card__header加 padding,破坏 element 纯展示语义
最容易被忽略的一点是:BEM 的 block 必须能独立存在。
card__header__title看似顺理成章,实则把 DOM 实现细节暴露给了 CSS,一旦结构微调,所有依赖它的样式都会悄无声息地失效。 - 正确写法:
该拆成独立 Block 还是加 Modifier
判断标准就一条:这个 UI 片段会不会在别处复用?是否拥有自己的逻辑或样式边界?











