骨架屏闪烁用 linear-gradient 背景动画实现,轻量兼容(含 IE10),避免 opacity 或多 DOM 方案;推荐语义化类名、1.5s 动画时长、background-size 200% 配合位移增强扫描感;加载完成需移除 skeleton 类并清除 background-image。

用 CSS 动画实现骨架屏闪烁,别碰 JavaScript
骨架屏闪烁本质是背景色渐变动画,不是重绘 DOM 或轮播图片。直接上 linear-gradient + animation 最轻量、兼容性最好,连 IE10 都能跑。JS 驱动反而容易卡顿、触发重排,还多一次资源加载。
常见错误是用 opacity 动画模拟“闪烁”,结果内容一出现就闪一下,用户体验反而更差;或者用多个 div 拼接动画,DOM 膨胀、维护困难。
- 只对骨架元素设
background-image,不改结构 - 动画时长控制在
1.5s左右,太快像抖动,太慢显卡顿 - 用
background-size: 200% 200%配合位移,比纯颜色过渡更有“扫描感”
骨架元素的 class 命名和样式模板
别用泛化的 .skeleton,容易和 UI 组件库冲突。推荐按区块语义命名,比如 .article-title-skeleton、.user-avatar-skeleton,方便后续精准覆盖或禁用动画。
下面这段可直接复制进 CSS:
立即学习“前端免费学习笔记(深入)”;
.skeleton {
background-color: #f5f5f5;
background-image: linear-gradient(
90deg,
transparent,
rgba(255, 255, 255, 0.3),
transparent
);
background-size: 200% 100%;
animation: skeleton-loading 1.5s infinite;
}
@keyframes skeleton-loading {
0% {
background-position: -200% 0;
}
100% {
background-position: 200% 0;
}
}
加载完成时如何干净地停掉动画
靠 JS 切 class 最稳妥,别用 animation-play-state: paused —— 它只是暂停,动画状态还在内存里,部分安卓 WebView 会继续耗电。
关键点是:动画停掉的同时,要清除 background-image,否则即使内容显示了,骨架的渐变层仍可能轻微透出(尤其浅色文字下)。
- 加载成功后执行:
element.classList.remove('skeleton') - 如果用框架(如 Vue/React),在
v-if或useState切换时同步控制 class - 避免用
setTimeout延迟移除 —— 网络快的时候,动画还没播完内容就出来了,视觉撕裂
移动端 Safari 和低版本 Android 的兼容写法
老版 UC 和微信内置浏览器对 background-size 百分比支持不稳定,动画会卡死或不触发。必须加一层 WebKit 前缀保底。
只需在原样式里补这三行:
-webkit-background-size: 200% 100%; -webkit-animation: skeleton-loading 1.5s infinite; animation: skeleton-loading 1.5s infinite;
另外,iOS Safari 对 @keyframes 内 background-position 的百分比解析有 bug,务必写成 -200% 和 200%,别用 0 或 100% 作中间态。
真正难处理的是字体抗锯齿导致的微弱闪烁 —— 不是动画问题,是系统渲染机制。如果项目对视觉一致性要求极高,得在骨架区域强制启用 -webkit-font-smoothing: antialiased,但代价是文字略细,需设计确认。



















