Skeleton
在结构已知时展示加载占位。中文惯用名:骨架屏。
稳定本期新增已接入
元信息
| 字段 | 值 |
|---|---|
| 规范 ID | component.skeleton |
| 名称 | Skeleton |
| 二级分类 | 反馈(feedback) |
| 用途 | 在结构已知时展示加载占位 |
| 描述 | 中文惯用名:骨架屏。 |
预览
静态结构:根节点 <div data-slot="skeleton">(animate-pulse rounded-md bg-muted,纯 CSS 脉冲);按 shape 叠加默认尺寸:line 映射 h-4 w-full(文本行)、circle 映射 rounded-full(默认 40×40,头像)、rect 映射 h-24 w-full(矩形块);width / height 覆盖默认尺寸(数字转 px,字符串按 CSS 长度原样下发)。复杂骨架由多个 Skeleton 自行拼装(如 circle 头像 + 多条 line 文本 + rect 块)。
DSL 结构
{
"type": "Skeleton",
"props": {
"shape": "line",
"width": "60%"
}
}何时用
何时使用
- 结构已知时的加载占位:首屏卡片、列表行、详情区,占位形状与最终内容一致以抑制布局跳动。
- 需要预告「这里将出现什么」:头像圆 + 文本行的组合比转圈更能说明版式。
- 内容结构固定、加载耗时不确定的区块(字段固定的详情、行数固定的列表)。
何时不用
- 局部按钮 / 行内的处理中指示:使用 Spinner,骨架表达的是「这里将出现什么」而非「正在处理」。
- 需要阻断区块交互的加载:使用 LoadingOverlay(遮罩 + Spinner)。
- 确定无数据:使用 Empty——骨架屏会让用户以为还在加载。
- 已知极快的局部刷新(骨架只闪一瞬):直接留白或不做占位,闪烁比空窗更差。
变体
| 变体 | 视觉形态 | 适用场景 |
|---|---|---|
| line 文本行(默认) | h-4 全宽圆角条 | 段落、标题行占位 |
| circle 圆形 | rounded-full,默认 40×40 | 头像、图标占位 |
| rect 矩形 | h-24 全宽圆角块 | 图片、图表、卡片封面占位 |
| 自定义尺寸 | width / height 覆盖默认值(数字或 CSS 长度) | 与真实内容尺寸对齐,避免加载完成后版式跳动 |
| 组合骨架 | 多个 Skeleton 拼装(头像 + 文本行 + 矩形块) | 卡片 / 列表行的整块占位 |
API 属性
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
shape | `'line' | 'circle' | 'rect'` |
width | `number | string` | — |
height | `number | string` | — |
className / style | string / CSSProperties | — | 通用:根节点 class 合并 / 内联样式 |
使用规范
- 骨架形状与最终内容对齐(行列数、圆角、尺寸):加载完成后布局不跳动,这是它优于 Spinner 的核心。
- 只在结构已知时使用:无法预估内容结构就改用 Spinner / LoadingOverlay,猜错的骨架会误导用户。
- 加载很快的局部刷新不要用骨架:一闪而过的灰块会被感知为页面抖动。
- 组合多个 Skeleton 时按真实版式排布(间距、对齐),并保持与数据态一致的行数上限。
- 数据加载失败要切换到 Empty / Result,不要让骨架无限脉冲。
正例
- ✓ 列表首屏:每行渲染 circle(头像)+ 两条 line(主副标题),行数与分页大小一致。
- ✓ 详情卡片:rect 占位图表区 + 多行 line 占位字段,形状与最终字段一一对应。
- ✓ 个人资料卡:circle 40×40 头像 + width 「60%」的姓名行 + width 「40%」的副标题行。
反例
- ✕ 确定无数据仍显示 Skeleton(用户以为还在加载,应使用 Empty)。
- ✕ 加载已知极快的局部刷新也用骨架(闪烁比留白更差)。
- ✕ 骨架形状与真实内容差异过大,加载完成后版式大幅跳变。
Design Token 映射
不适用:组件 tokenRefs 为空:样式 Token 数据尚未接入,三层映射(Primitive → Semantic → Component)待样式 Token 接入后回填。