出现三级下划线说明组件划分失当:list等本应独立复用的结构被错误降级为私有子元素,正确做法是将其提级为独立block(如list)并用modifier(如list--in-card)表达上下文变体。

出现 .block__element__subelement 这类三级下划线,说明 BEM 结构已经失控——它不是命名太长的问题,而是组件划分逻辑出了偏差。
为什么 .card__body__list__item 是错的
浏览器和人都不关心你写了几个下划线,但这个写法暴露了两个硬伤:一是 list 本该是独立可复用的 Block,却被塞进 card__body 当成私有子结构;二是 CSS 选择器若因此写成 .card__body .list__item,就退化回传统嵌套陷阱,权重高、易冲突、挪位置就失效。
- 判断标准很简单:
list会不会在侧边栏、弹窗、表单里也出现?只要答案是“会”,它就必须是独立 Block -
card__body只负责布局容器语义,不承担列表逻辑;list才负责数据项排列、间距、交互反馈 - 强行压平成
.card__body__list__item不仅让类名难读,还让list__item失去脱离卡片复用的能力
怎样把深层嵌套转成合法 BEM
核心动作就一个:把中间层“提级”为 Block。不是改名字,是重构职责边界。
- 原结构:
<div class="card"><div class="card__body"><ul class="card__body__list"> <li class="card__body__list__item"> → 全部删掉</li> <li>新结构:<code><div class="card"><div class="card__body"> <ul class="list"> <li class="list__item"> <li>如果列表确实只在卡片内有特殊样式(比如缩进更小),加 Modifier:<code>list--in-card,而不是靠父级类名推导 - 绝对不要写
.card__body .list这种后代选择器;CSS 中只允许.list、.list__item、.list--in-card等单类名规则
哪些场景看似需要三层,其实该用 Modifier
当某个元素的行为/外观只因所处上下文而变,且不改变其本质结构时,Modifier 比嵌套更干净。
- 按钮在卡片内需缩小:
button--in-card✅,不是.card__body__button❌ - 标题在模态框中要加阴影:
heading--modal-shadow✅,不是.modal__content__heading❌ - 修饰符名称必须聚焦状态或行为,禁用位置词:
--in-card可接受(已约定上下文),但--inside-header是坏味道 - Modifier 必须能独立生效:
.button--in-card在任何地方加都应有预期效果,不依赖.card存在
真正容易被忽略的不是“怎么起名”,而是每次写新类名前是否问过一句:这个 UI 片段,下次出现在另一个页面时,我愿不愿意直接复制粘贴这段 HTML 和 class?如果犹豫了,大概率它不该是 element,而该是一个 block。











