空状态组件必须命名为语义完整、可独立存在的 Block 名如 empty-state;它需自包含渲染逻辑与交互能力,禁止用 empty 或 no-data 等缺失业务语义的名称,且 Modifier 必须作用于 Block 根而非 Element。

空状态组件不能叫 empty、no-data 或 placeholder,必须用语义完整、可脱离上下文独立存在的 Block 名,比如 empty-state;它要能自己渲染出可用界面(含图标、标题、描述、操作按钮),不依赖父容器提供字体、颜色或间距。
为什么不能用 empty 或 no-data 作为 Block 名
这类名字缺失业务语义和复用边界:empty 是形容词,不是组件;no-data 描述的是条件而非功能——它没说明“谁”空了、“为什么”空、“用户接下来该做什么”。一旦在订单页、搜索页、侧边栏同时复用,就会被迫加前缀(如 order__empty),破坏 BEM 的块级自治原则。
正确做法是把“空状态”当作一个完整交互单元来建模:empty-state 暗示它自带图标渲染、文案排版、按钮响应、ARIA 属性(如 aria-live="polite"),哪怕单独丢进 <div></div> 也能正常显示和聚焦。
-
empty-state必须包裹全部内容:图标、主标题、副描述、操作按钮(empty-state__action) - 禁止写成
card__empty或list__no-results—— 这些是 Element 命名,说明它还没抽离成独立 Block - 如果某处需要“无搜索结果”的变体,应通过 Modifier 表达:
empty-state--no-results,而不是新建 Block
empty-state__icon 为什么不能带 --loading 或 --error 这类修饰符
图标本身没有“加载中”或“出错”的状态,那是整个空状态组件的状态。把 --loading 挂在 empty-state__icon 上,等于把逻辑责任错配给子元素,导致 CSS 难维护、JS 状态难同步。
立即学习“前端免费学习笔记(深入)”;
正确方式是让 Modifier 作用于 Block 根:empty-state--loading 控制整体视觉(比如图标旋转 + 文案变“加载中…”),再用后代选择器统一调整内部元素样式:
.empty-state--loading .empty-state__icon {
animation: spin 1s infinite;
}
.empty-state--loading .empty-state__title {
content: "加载中...";
}
-
empty-state__icon只负责基础尺寸、对齐、默认颜色;所有动态变化由 Block 级 Modifier 触发 - 禁止写
empty-state__icon--loading—— 它违反 “Modifier 不应下沉到 Element” 原则 - 如果图标需支持 SVG 替换(如暗色模式切换),用
empty-state--dark统一控制,而非给图标加新类
如何让 empty-state 在不同容器里保持一致渲染
关键不是靠父容器重置样式,而是让每个类名自包含全部必要声明。例如 empty-state__title 必须显式写 font-size、line-height、margin、color,不能只设 font-weight: bold 然后指望父级给字号。
- 所有尺寸单位用
rem,禁用em(避免被外层font-size连锁缩放) -
line-height必须用无单位值(如1.4),不写1.4rem -
empty-state__action必须设display: inline-flex或display: block,不能依赖父容器的text-align居中 - 禁用
!important—— 如果发现某处样式被覆盖,说明 Block 缺少某个必要声明,不是靠权重硬顶
真正难的不是命名规则,而是判断“这个空状态是否真的能脱离当前页面逻辑独立存在”。比如带“去设置”按钮的 empty-state,如果跳转链接由父组件动态传入,那它就还没达到原子级复用标准——得补上 data-action 属性或 JS 初始化契约,否则挪到新页面就只剩文案,按钮点不动。


















