应使用 skeleton 作为块名。因其表达骨架屏这一独立视觉组件的语义,而非临时状态 loading;元素名需反映占位角色(如 skeleton__item),非真实内容语义;修饰符须显式声明尺寸、圆角等变量,禁用模糊或设备依赖命名;动画与无障碍控制均应在块级作用域内实现。

如何给 BEM 块命名:skeleton 还是 loading?
直接用 skeleton 作为块名更准确。BEM 要求块名表达语义而非状态,loading 是临时状态,而骨架屏是独立的视觉组件——它可能出现在数据加载、缓存未命中、甚至 SSR 首屏渲染阶段。用 skeleton 可避免后续扩展时(比如加「空状态 fallback」或「错误占位」)被迫重命名或嵌套混乱。
元素命名要匹配真实 DOM 结构,别硬套“内容类型”
常见错误是写成 skeleton__title、skeleton__avatar,但实际 HTML 往往没有 <h2> 或 <img> 标签,只有一堆 <div>。BEM 元素名应反映其在骨架中的角色,而非将来真实内容的语义:
-
skeleton__item(列表项容器) -
skeleton__media(图片/头像占位区) -
skeleton__text-line(单行文字占位) -
skeleton__text-paragraph(多行段落占位)
这样既保持 BEM 的可维护性,又避免骨架层和真实内容层的 class 名产生隐式耦合。
修饰符必须覆盖尺寸、圆角、比例等关键视觉变量
骨架屏的响应式适配不靠媒体查询驱动,而靠修饰符显式声明。因为 CSS 无法动态读取真实图片宽高,所有尺寸必须预设:
立即学习“前端免费学习笔记(深入)”;
-
skeleton--aspect-16-9对应aspect-ratio: 16 / 9,iOS Safari 15.4+ 支持;老版本 fallback 用padding-top: 56.25%+position: relative -
skeleton--radius-m统一设为border-radius: 8px,比skeleton--radius-s(4px)更常用于卡片类组件 -
skeleton--width-60表示宽度为父容器 60%,用于模拟标题长度,别用skeleton--short这种模糊词
修饰符名必须可枚举、可组合,禁止出现 skeleton--mobile 这类设备依赖型命名——骨架屏本身不感知设备,只响应布局上下文。
伪元素动画层必须隔离在块内,不能污染元素样式
扫光动画用 skeleton::after 实现,但这个伪元素属于块级作用域,不能写成 skeleton__text-line::after。原因有三:
- 多个子元素共用同一动画起点,否则光效错位(比如头像和标题的高光不同步)
- 伪元素需覆盖整个块区域,
inset: 0才能保证圆角裁剪生效;若挂到元素上,overflow: hidden失效 - 无障碍支持
@media (prefers-reduced-motion: reduce)必须作用于块级,否则部分骨架仍会闪动
所以动画控制逻辑全收在 skeleton 块里,子元素只负责尺寸与形状,不参与动效。


















