骨架屏用多层linear-gradient模拟色块形状,配合radial-gradient画头像、横向渐变画标题段落,并通过background-size/position控制尺寸与留白,结合shine动画实现流动效果,响应式采用rem和aspect-ratio保障兼容性。

用 linear-gradient 模拟骨架屏的色块形状
骨架屏本质不是图片,而是用背景渐变“画”出容器轮廓。关键在于让 background-image 的 linear-gradient 覆盖真实内容区域,同时保持透明间隙模拟文字/头像留白。
常见错误是直接给整个容器设单一渐变,结果所有区域颜色一致,看不出段落结构。正确做法是分层控制:用多个 linear-gradient 叠加,每个对应一个占位区块(如头像圆角、标题长条、段落短横线)。
- 头像占位:用
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 - 段落行:重复横向渐变,
background-size: 100% 12px,再用background-repeat: repeat-y
用 animation 让骨架“流动”起来
纯静态灰色块没有加载感,必须加横向扫光动画。核心是移动渐变起始点,不是移动整个背景图。
容易踩的坑是写成 background-position: 100% 0 → 0 0 这种位移,实际会因重复导致闪烁或跳变。正确方式是固定背景尺寸,只动渐变方向上的偏移量:
立即学习“前端免费学习笔记(深入)”;
- 定义动画:
@keyframes shine { from { background-position: -200% 0; } to { background-position: 200% 0; } } - 绑定到元素:
background: linear-gradient(90deg, transparent, #e0e0e0, transparent); animation: shine 2s infinite; - 注意:
background-size必须设为宽度大于容器(如200% 100%),否则动画无效果
响应式下如何避免骨架屏错位或溢出
移动端屏幕窄,但骨架图若按 PC 宽度设计,缩放后圆角变尖、文字行变窄,看起来像 bug。
根本解法不是媒体查询改所有值,而是用相对单位统一锚定:
- 所有
background-size和background-position用em或rem,比如background-size: 8rem 1.2rem - 圆角头像用
border-radius: 50%+aspect-ratio: 1,不依赖固定像素 - 禁用
background-attachment: fixed,它在 iOS Safari 下会导致动画卡顿甚至失效 - 测试真机时重点看 Safari —— 它对
background-blend-mode和多层渐变叠加支持较弱,慎用
为什么不用 SVG 或 Canvas 做骨架屏
SVG 看似灵活,但路径需手动适配每种布局,维护成本高;Canvas 需 JS 渲染,违背“纯 CSS 加载中占位”的轻量初衷。
更现实的问题是性能和兼容性:
- SVG
<use></use>在部分 Android WebView 中无法正确继承样式,渐变失效 - Canvas 绘制会触发重排,首屏渲染延迟比纯 CSS 高 30ms+(实测 Nexus 5X)
- SSR 场景下 Canvas 无法服务端输出,而 CSS 骨架可随 HTML 一并下发
真正复杂的交互型骨架(比如带波纹扩散的按钮)才值得上 SVG;列表、卡片这类结构化内容,linear-gradient + animation 就够用,而且容易被开发者一眼看懂逻辑在哪崩了。


















