必须用skeleton而非loading,因bem块名须表达独立视觉组件的语义完整性,而非临时状态;骨架屏可能出现在ssr首屏、缓存未命中等非请求场景,用loading会导致后续扩展空状态或错误占位时命名体系崩溃。

直接用 skeleton 作为块名,不是 loading;它不是临时状态,而是一个独立视觉组件。
为什么必须用 skeleton 而非 loading?
因为 BEM 的块名要表达语义完整性,而非运行时状态。loading 描述的是“正在请求”,但骨架屏可能出现在 SSR 首屏、缓存未命中、甚至离线 fallback 场景——它不依赖网络请求。一旦你用 loading 命名,后续加空状态(empty)或错误占位(error)时,就会被迫重构整个命名体系或陷入嵌套混乱。
常见错误:loading--skeleton 这类写法看似合理,实则把两个独立块(loading 和 skeleton)强行耦合,违反 BEM “块间隔离”原则。
skeleton__item 这类元素名怎么定才不翻车?
元素名必须匹配真实 DOM 结构,而不是未来内容的语义。骨架层和真实内容层不能隐式绑定。
- 错:写成
skeleton__title或skeleton__avatar,但实际 HTML 只有一堆<div> —— 这会让后续替换真实内容时,样式逻辑被误认为“标题必须存在” <li>对:用角色导向命名,如 <code>skeleton__item(列表项容器)、skeleton__media(图片/头像占位区)、skeleton__text-line(单行文字占位)、skeleton__text-paragraph(多行段落占位) - 特别注意:
skeleton__media不等于skeleton__image—— 因为骨架中可能是圆角头像、长宽比固定的 banner,也可能是图标占位,media更抽象、更可复用 - 尺寸类必须显式:如
skeleton--width-60(宽度 60%),禁用skeleton--short这类模糊词 - 圆角统一用语义化层级:
skeleton--radius-s(4px)、skeleton--radius-m(8px),别写skeleton--rounded - 比例控制优先用
aspect-ratio,修饰符如skeleton--aspect-16-9;老浏览器 fallback 必须在同一修饰符下完成(如用padding-top: 56.25%+position: relative) - 严禁设备依赖型命名:
skeleton--mobile是错的——骨架屏本身不感知设备,只响应父容器的布局行为 - 原因一:多个子元素需共用同一动画起点,否则高光在
__media和__text-line上不同步 - 原因二:
::after需覆盖整个块区域(inset: 0),才能让圆角裁剪生效;若挂到元素上,overflow: hidden在父级失效 - 原因三:无障碍控制(
@media (prefers-reduced-motion: reduce))必须作用于skeleton块级,否则无法统一关闭所有子元素动画
修饰符命名有哪些硬性约束?
修饰符不是随便加的标签,它必须对应可枚举、可组合、与布局上下文无关的视觉变量。
动画和无障碍控制该挂在哪一级?
扫光动画必须用 skeleton::after,不能写成 skeleton__text-line::after。
最容易被忽略的一点:伪元素动画和修饰符必须同级声明。比如加了 skeleton--radius-m,就得确保 skeleton::after 的 border-radius 也同步继承或重置,否则圆角区域外会漏出扫光残影。











