user-avatar 是独立 Block,因跨场景复用、语义自洽、边界清晰;card__image__caption 非法,因 Element 不可嵌套;card--user 与 card--product 应拆为 user-card 和 product-card 两个 Block。

card 是 Block,user-avatar 不是 card__avatar
卡片组件中,card 本身是 Block,因为它能独立渲染、有完整语义(如展示内容摘要、操作入口)、可在列表页、详情页、弹窗中复用。而 user-avatar 出现在用户卡片、评论区头像、个人主页等多个上下文,它具备跨场景复用能力、语义自洽、边界清晰——所以它必须是独立的 Block,不是 card__avatar。
常见错误是把视觉上“在卡片里”当成逻辑上“属于卡片”。BEM 关注的是复用意图和语义归属,不是 DOM 嵌套位置。
-
user-avatar应有自己完整的样式文件:user-avatar.css,不依赖card.css - 如果强行写成
card__avatar,后续在评论区复用时就得复制样式或加 hack,违背 BEM 的可维护初衷 - HTML 中
user-avatar可以作为card的子节点,但 CSS 上两者无父子选择器依赖:.card .user-avatar是反模式
card__title 和 card__image 是 Element,但 card__image__caption 不合法
card__title 和 card__image 是合法 Element,因为它们:只在 card 内部有意义、不能脱离 card 独立使用、没有跨组件复用需求。但一旦出现 card__image__caption,就违反了 BEM 最核心的一条规则:Element 必须是 Block 的直系组成部分,不允许嵌套 Element。
正确做法是把 caption 提升为 card__caption(如果它只服务于 card),或单独抽成 image-caption Block(如果它也用于 banner、gallery 等)。
立即学习“前端免费学习笔记(深入)”;
- BEM 不模拟 DOM 层级,
__表示“属于 card 的某个部分”,不是“DOM 子节点的子节点” -
card__image--rounded合法,card__image__caption非法,哪怕 HTML 结构是<div class="card__image"><span class="card__image__caption"> <li>双下划线 <code>__后只能跟一个单词,不能带连字符或第二个__ - 这个 UI 单元是否在项目中至少两个不同上下文出现过?(如
search-form在首页、侧边栏、弹窗都存在) - 去掉它所属的父容器后,它还能否被开发者一眼识别出功能和用途?(
notification-badge可以,card__badge不行) - 它的样式是否可能被其他 Block 直接复用,而无需修改类名或加覆盖规则?(
icon-download可被button、card、list-item共用) -
card--type-user是典型误用:把业务分类当视觉变体,导致样式文件膨胀、语义模糊 - 真正需要的是两个 Block 文件:
user-card.css和product-card.css,各自定义user-card__avatar和product-card__price - 共用逻辑可通过 JS 组件抽象,CSS 层面保持 Block 独立
如何验证一个类名该是 Block 还是 Element?
问三个问题,任一答案为“是”,它就该是 Block:
如果全是否定,再检查它是否满足 Element 的两个硬性条件:HTML 中必须是 card 标签的直接子节点;CSS 中不能有 .card > .card__xxx 这类强耦合写法——BEM 的 Element 是语义直系,不是 DOM 直系,但应尽量贴近。
modifier 不能替代 Block 拆分
看到 card--user 和 card--product,别急着加 modifier。先确认:这两者是否共享同一套 DOM 结构、交互逻辑、状态管理?如果不是,比如用户卡片带关注按钮、产品卡片带价格和加入购物车,那它们本质是两个 Block:user-card 和 product-card。
Modifier 只适用于可预测、有限、视觉/行为差异小的变体,比如 card--featured(仅多一个角标和阴影),而不是承载不同业务逻辑的“类型”。


















