纯css骨架屏必须用两层linear-gradient叠加(底层结构+上层扫光)配合background-position动画实现,因opacity和transform在ios safari及安卓webview中易发虚、掉帧;background-position仅改变绘制起点,不重排不重绘,gpu加速稳定且像素精准。

纯 HTML + CSS 就能实现骨架屏,不需要 JS 控制加载逻辑,但必须用 background-image 或 linear-gradient 配合 background-position 动画 —— 其他方式(如 opacity、transform)在 iOS Safari 和低端安卓 WebView 上容易发虚、掉帧或闪烁。
为什么不能直接用 opacity 或 transform 做骨架动画
因为 opacity 只改透明度,看不出结构浮现;transform: translateX() 会触发重排,在 Safari 和部分安卓 WebView 中边缘发虚、锯齿明显。而 background-position 动画只改变渐变绘制起点,不重排不重绘,GPU 加速稳定,像素对齐精准。
常见错误是写成 transform: translateX(100px) 或 opacity: 0.5 → 1,结果在 iOS 上光效卡顿、低端机掉帧。正确做法始终锁定 background-position 的 x 轴位移。
- 必须搭配
background-repeat: no-repeat,否则重复背景导致光条跳变 - 起始值要带单位:
background-position: -200px 0,不能写成-200 0(IE/旧 Chrome 会忽略) - 动画缓动必须用
linear,ease会让光效在两端滞留,破坏流动感
怎么用 linear-gradient 分层模拟结构轮廓
单层渐变只能铺色,无法同时表达「结构」和「扫光」。必须用两层 linear-gradient 叠加:底层画结构(头像、标题、段落),上层是半透扫光条。
关键陷阱在于两层必须共用同一组 background-size 和 background-position,否则动画错位、光条漂移。
- 头像占位:
radial-gradient(circle, #f0f0f0 0%, #f0f0f0 50%, transparent 50%)+background-size: 40px 40px - 标题占位:
linear-gradient(to right, #f0f0f0 0%, #e0e0e0 50%, #f0f0f0 100%)+background-size: 200px 16px - 段落行:
linear-gradient(to right, #f0f0f0 0%, #e0e0e0 50%, #f0f0f0 100%)+background-size: 100% 12px+background-repeat: repeat-y -
background-size必须设为固定像素(如200px 100%),rem、vw在 iOS Safari 中完全失效
怎么让扫光动画真正“流动”起来
核心是移动渐变起始点,不是移动整个背景图。错误写法是 background-position: 100% 0 → 0 0,会导致重复区域跳变或闪烁。
正确方式是固定背景尺寸,只动渐变方向上的偏移量:
@keyframes shine {
from { background-position: -200px 0; }
to { background-position: 200px 0; }
}
.skeleton-line {
background: linear-gradient(90deg, transparent, #e0e0e0, transparent);
background-size: 200px 100%;
animation: shine 2s infinite linear;
}
-
background-size必须大于容器宽度(如200px 100%),否则动画无效果 - 动画时长建议 1.5–2.5s,太快显得焦躁,太慢失去反馈感
- 别用
filter: blur()模拟灰度 —— 在部分 iOS Safari 上有性能抖动
真实图片加载完成后怎么平滑切换
骨架屏本质是视觉占位,不是“先显示灰色图再换真图”。真实 <img> 加载完成时,应通过 opacity 或 visibility 切换显隐,而不是 display: none —— 后者会让元素从流式布局中消失,引发重排。
- 给骨架容器设固定宽高或使用
aspect-ratio: 16 / 9(Chrome 88+ 支持),避免父容器塌陷 - 加载完成时必须同步销毁动画并释放内存,不能只靠
display: none或visibility: hidden——@keyframes动画仍在后台运行,长期驻留影响页签性能 - 若用 JS 动态插入内容,建议监听
img的load事件,或用IntersectionObserver判断可视区加载完成再切换状态 - SSR 输出骨架时,必须同步注入数据加载状态,否则前端 hydration 会失败或重复拉取
最易被忽略的点:两层渐变的 background-size 和 background-position 必须严格耦合;iOS Safari 对 rem 和 vw 作为 background-size 单位完全不支持;动画销毁不彻底会在单页应用中反复进入/退出时持续拖慢页面。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











