empty-state 应为独立 block,类名仅用 empty-state,子元素用双下划线命名,modifier 表达业务状态而非样式微调,须显式添加类控制显示,禁用 :empty 伪类。

空状态容器本身就是一个独立 Block
别把它塞进 product-list 或 user-card 里当子元素处理——empty-state 是功能闭环的 UI 单元:有图标、标题、描述、操作按钮,能脱离上下文复用。它该是顶层 Block,类名就叫 empty-state,不是 product-list__empty。
常见错误是写成 .list__empty,结果在搜索页复用时,样式依赖 .list 存在;一旦单独渲染,整个空状态就失联。BEM 要求 Block 自包含,HTML 中必须显式声明:<div class="empty-state"></div>,不靠父级类名“猜”作用域。
empty-state__icon、empty-state__title 这些是标准 Element
每个视觉可识别的组成部分都应是 empty-state 的直接子 Element,用双下划线连接:
-
empty-state__icon:图标容器,支持 SVG 或 img,不承担文案逻辑 -
empty-state__title:主标题,语义明确,不和empty-state__desc混用 -
empty-state__action:按钮或链接区域,可含多个按钮,但整体为一个 Element
禁止写 empty-state__title--large——尺寸是整个 Block 的变体,该用 Modifier 控制:empty-state--compact 或 empty-state--full-width,并在内部重置子元素尺寸。
Modifier 用于区分业务场景,不是视觉微调
empty-state--no-icon、empty-state--with-cta、empty-state--search-empty 这类 Modifier 表达的是真实业务状态,不是“让图标变小一点”这种样式修补。
容易踩的坑:
- 把
empty-state--light当主题色开关,结果深色模式下全站要加另一套--dark,违背 BEM 的语义稳定性原则 - Modifier 单独使用,比如只写
<div class="empty-state--search-empty"></div>,没带基础empty-state类——这会破坏选择器匹配和复用链 - 用 Modifier 控制响应式断点,如
empty-state--mobile,实际该由媒体查询 + 基础类控制,Modifier 只管内容态
和 :empty 伪类配合时,类名驱动比 CSS 猜测更可靠
:empty 在真实项目中几乎总失效——模板缩进、React 注释节点、Vue 的 v-if 占位符都会让它判空失败。所以不要写 .empty-state:empty { display: block; }。
正确做法是让业务逻辑决定状态,并显式加类:
- JS 清空列表后:
el.classList.toggle("empty-state--active", list.length === 0) - 服务端直出:
<div class="empty-state empty-state--search-empty" data-empty="true"></div> - CSS 响应:
.empty-state--active { display: flex; }或[data-empty="true"] .empty-state { display: flex; }
真正麻烦的不是写法,而是团队里有人偷偷用 display: none 隐藏内容来“模拟空”,却不改类名——这时候 empty-state--active 还挂着,样式和 DOM 状态彻底脱钩。BEM 管得住命名,管不住人,得靠 Code Review 卡住这类操作。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











