
2026/7/1 · 8:11
UI 动效 007:Skeleton Shimmer,为什么灰色占位条会扫一下
这期拆解 Skeleton Shimmer / 骨架屏扫光:它适合页面结构已确定但数据还没返回的场景,关键是先画出接近真实内容的占位骨架,再用渐变扫光和内容淡入降低等待感。文中用自制 GIF 与 CSS 示例说明怎么让灰色占位条动起来。
一张卡片还没加载出来,页面先出现几条灰色圆角块;过一会儿,一束浅色高光从左到右扫过去,真实内容再淡进来。这个动效通常叫 Skeleton Shimmer / 骨架屏扫光。它不是真的让接口更快,而是先告诉用户「这里会有什么」,避免页面空白得像坏了一样。
Material Design 3 把 Skeleton loaders 归在转场模式里:它们用临时 loading state 过渡到完整 UI,并用内容即将出现的位置降低感知等待和版式跳动。1 NN/g 对 skeleton screen 的定义也很接近:加载时显示一个类似线框图的页面结构,让用户先建立对最终页面的预期。2

它适合什么时候用
Skeleton Shimmer 最适合「页面结构确定,但数据还没回来」的场景:信息流卡片、商品列表、用户资料页、仪表盘模块都可以用。MUI 的 Skeleton 组件文档也把它定义为「数据加载前显示内容预览」,并提供 text、circular、rectangular 等形状,动画可以是默认 pulsate,也可以改成 wave 或关闭。3
别把它当万能 loading。NN/g 的建议很直接:skeleton 更适合全页或大块内容加载;单个卡片、视频模块可以用 spinner;超过 10 秒的等待更应该给 progress bar,因为用户需要知道还要等多久;如果页面 1 秒内就出来,闪一下 skeleton 反而会烦。2
我一般用这三条判断要不要上:
- 内容版式稳定:标题、图片、摘要、按钮这些位置基本固定,骨架才有意义。
- 等待不是瞬间结束:太短会闪屏,太长会让用户觉得被糊弄。
- 真实内容能渐进替换:拿到哪块数据就替换哪块,不要等全部接口完成后才一起出现。
为什么扫一下会让等待更「有方向」
骨架屏有两个层次。第一层是灰色块,它让用户看到最终页面的大致结构;第二层是 shimmer,也就是那束移动高光。高光的作用不是装饰,而是告诉用户「系统还在工作」。Material Design 3 也提到,skeleton loaders 会用细微的 pulsing animation 表示不确定进度,内容加载完后再快速淡入。1
这和 spinner 的心理感受不一样。Spinner 只说「请等一下」,但没有告诉你等完会看到什么;骨架屏先把版式摆出来,用户的眼睛会自然预读那些灰色区域:这里是头像,这里是标题,这里可能是图片。等真实内容出现时,变化就不是突然砸下来,而是「影子变成实体」。
扫光要轻。太亮、太快、循环太密,会抢走用户对内容本身的注意力。NN/g 也提醒,animated skeleton 可能造成分心、烦躁,甚至带来可访问性问题。2 所以它更像呼吸灯,不该像舞台追光。
实现原理:固定骨架 + 移动渐变
Web 端最常见的做法是把每个占位块画成圆角矩形,再给它叠一层线性渐变。CSS 的
linear-gradient() 可以生成沿直线变化的颜色带,MDN 对 CSS gradients 的说明里也提到,渐变可以直接作为背景使用。4高光怎么动?把背景做得比元素本身更宽,然后用
background-position 改变背景图的位置。MDN 对 background-position 的定义是:它设置每个背景图的初始位置。5 再用 @keyframes 定义从起点到终点的中间步骤,浏览器就会把这束高光平滑扫过去;@keyframes 本来就是用来控制 CSS 动画序列中间步骤的规则。6.skeleton {
border-radius: 12px;
background: linear-gradient(
100deg,
#e6ebf4 0%,
#e6ebf4 38%,
#ffffff 50%,
#e6ebf4 62%,
#e6ebf4 100%
);
background-size: 220% 100%;
animation: shimmer 1.2s linear infinite;
}
@keyframes shimmer {
from { background-position: 120% 0; }
to { background-position: -120% 0; }
}
@media (prefers-reduced-motion: reduce) {
.skeleton { animation: none; }
}这段代码里最重要的不是颜色,而是三件事:
- 骨架尺寸要接近真实内容。标题不要画成长段,头像不要画成方块。占位越像最终内容,替换时越稳。
- 高光只改变背景,不改变布局。不要用真正的元素横向移动,否则会多出重排和遮挡问题。
- 真实内容淡入,骨架淡出。直接把骨架删掉会出现跳变;短暂交叉淡入能让视觉更顺。
做坏时,问题通常不在动画,而在版式
Skeleton Shimmer 很容易被做成「一屏灰条」。灰条数量太多,用户会看不出层级;灰条和最终内容差得太远,内容出现时还是会跳;页面已经很快,却硬要先闪一层 skeleton,体验会更碎。
一个好用的骨架屏应该像低保真预览:图片区域就是图片比例,标题区域只给一两行,次要信息更淡一点,按钮和头像保留形状。移动的高光只负责说明「还在加载」,真正降低焦虑的是稳定的结构。
如果只能记一条:先画对影子,再让影子轻轻动一下。Skeleton Shimmer 的动效不是主角,主角是用户在等待时仍然知道自己将要看到什么。

このコンテンツについて、さらに観点や背景を補足しましょう。