css动画怎么实现加载占位_css动画骨架屏思路

骨架屏是视觉占位与渐变过渡组合,用linear-gradient+background-position动画模拟扫描光效,需固定尺寸、脱离文档流、JS控制显隐,并适配SSR/CSR渲染时机。

animation + keyframes 模拟骨架屏闪烁效果

骨架屏本质不是“加载中动画”,而是视觉占位+渐变过渡的组合。CSS 动画只负责「模拟内容未就绪时的视觉节奏」,不参与数据加载逻辑。核心是用 linear-gradient 生成灰白条状背景,再通过 animation 移动 background-position 制造扫描光效。

  • 推荐使用 to right 方向的线性渐变,比径向更易控制扫描节奏
  • 动画时长建议设为 1.5s ~ 2.5s,太短显急促,太长降低感知响应
  • 必须加 background-size: 200% 100%,否则 background-position 位移无效
@keyframes loading-skeleton {
  0% { background-position: -200% 0; }
  100% { background-position: 200% 0; }
}

.skeleton {
  background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
  background-size: 

200% 100%; animation: loading-skeleton 2s ease-in-out infinite; }

骨架元素需脱离文档流避免重排

如果直接给 加骨架样式,内容加载后替换会触发 layout shift(布局偏移),造成页面抖动。正确做法是让骨架层和真实内容共用同一容器,用 position: absolute 叠加,或用 visibility: hidden 控制显隐而非 display: none

  • 骨架容器设 position: relative,内部骨架元素设 position: absolute; top: 0; left: 0; width: 100%; height: 100%
  • 真实内容加载完成时,用 JS 切换类名,把骨架元素 visibility: hidden,而不是移除 DOM
  • 避免对骨架元素设置 height: auto,必须固定高度或用 aspect-ratio 保形

不同组件需定制化骨架结构

按钮、头像、卡片的骨架形态差异大,不能靠一个 class 全局覆盖。比如头像要圆角+渐变遮罩,列表项需等高行高+多段灰条,而按钮需要宽度自适应+内边距留白。

  • 头像骨架:border-radius: 50% + background-image: radial-gradient(...)
  • 文字行骨架:用多个 ,每行设不同 width 模拟长短文本
  • 避免用伪元素 ::before 做骨架——它无法继承父容器的宽高约束,响应式下容易错位
.avatar-skeleton {
  border-radius: 50%;
  background: radial-gradient(circle, #f5f5f5 20%, #e8e8e8 80%);
}

.skeleton-line {
  display: block;
  height: 16px;
  margin: 8px 0;
  background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
  background-size: 200% 100%;
  animation: loading-skeleton 2s ease-in-out infinite;
}

SSR 或首屏直出时骨架屏容易失效

服务端渲染(SSR)或静态生成(SSG)页面首次加载时,骨架屏可能一闪而过甚至不出现,因为 HTML 已含真实内容,JS 还没执行完。此时需配合服务端逻辑,在数据未就绪时主动输出骨架 HTML 片段。

  • Next.js / Nuxt 等框架中,骨架应作为 fallback 组件写在 loading.tsxloading.vue 中,由框架自动接管
  • 纯 CSR 项目可在组件挂载前用 useState(false) 控制骨架显隐,但首次渲染仍需同步判断 data === null
  • 关键点:骨架屏是否生效,取决于「HTML 输出时机」和「JS 渲染时机」的竞态关系,不能只靠 CSS 动画
骨架屏最难的不是动画本身,而是如何让它在各种渲染模式下稳定介入 DOM 生命周期 —— CSS 负责动效,JS 负责时机,HTML 结构负责占位精度,三者缺一不可。