在前端开发中,页面加载等待体验直接影响用户留存率。当接口请求较慢、图片资源未加载完成时,页面会出现空白或闪烁,体验极差。
骨架屏(Skeleton Screen)就是解决这个问题的最优方案之一 —— 它在数据加载前展示页面的占位轮廓,让用户感知到「内容正在加载」,比传统的 loading 动画更流畅、更直观。
今天教大家零依赖、纯 HTML+CSS实现骨架屏,不用插件、不用框架,复制即用,适配所有前端项目!
二、什么是骨架屏?
简单说:页面内容的「轮廓占位符」。
在数据 / 图片加载完成前,用灰色渐变的占位块模拟页面结构,加载完成后替换为真实内容,是现在主流 APP / 网站(知乎、掘金、B 站、抖音)的标配加载方案。
三、实现核心原理
- HTML:搭建和真实页面结构一致的占位骨架(div 模拟卡片、文字、图片)
- CSS:
- 基础样式:灰色背景、圆角、间距,模拟内容轮廓
- 动画:线性渐变位移,实现流畅的流光效果(核心)
- 无 JS、无图片、无第三方库,极致轻量
四、完整代码实现(直接复制可用)
1. 完整 HTML+CSS 代码
html
预览
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>纯CSS骨架屏实现</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
padding: 20px;
background-color: #f5f5f5;
}
/* ====================== 骨架屏核心样式 ====================== */
.skeleton {
/* 基础背景色 */
background: #f2f2f2;
/* 禁止内容撑开 */
overflow: hidden;
position: relative;
}
/* 流光动画核心 */
.skeleton::before {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
/* 渐变背景:实现流光效果 */
background: linear-gradient(90deg,
transparent,
rgba(255, 255, 255, 0.6),
transparent
);
/* 动画:名称 时长 线性 无限循环 */
animation: skeleton-loading 1.2s infinite linear;
}
/* 流光动画关键帧 */
@keyframes skeleton-loading {
0% {
transform: translateX(-100%);
}
100% {
transform: translateX(100%);
}
}
/* ====================== 页面布局样式 ====================== */
/* 卡片容器 */
.card {
width: 100%;
max-width: 400px;
background: #fff;
border-radius: 12px;
padding: 16px;
margin: 0 auto 20px;
box-shadow: 0 2px 12px rgba(0,0,0,0.08);
}
/* 头像骨架 */
.skeleton-avatar {
width: 50px;
height: 50px;
border-radius: 50%;
margin-bottom: 12px;
}
/* 标题骨架 */
.skeleton-title {
width: 70%;
height: 20px;
border-radius: 4px;
margin-bottom: 10px;
}
/* 文字骨架 */
.skeleton-text {
width: 100%;
height: 14px;
border-radius: 4px;
margin-bottom: 8px;
}
.skeleton-text:last-child {
width: 60%;
}
/* 图片骨架 */
.skeleton-img {
width: 100%;
height: 180px;
border-radius: 8px;
margin: 12px 0;
}
</style>
</head>
<body>
<!-- 单个卡片骨架屏 -->
<div class="card">
<!-- 头像 -->
<div class="skeleton skeleton-avatar"></div>
<!-- 标题 -->
<div class="skeleton skeleton-title"></div>
<!-- 文字行 -->
<div class="skeleton skeleton-text"></div>
<div class="skeleton skeleton-text"></div>
<div class="skeleton skeleton-text"></div>
<!-- 图片 -->
<div class="skeleton skeleton-img"></div>
</div>
<!-- 可复制多个卡片 -->
<div class="card">
<div class="skeleton skeleton-avatar"></div>
<div class="skeleton skeleton-title"></div>
<div class="skeleton skeleton-text"></div>
<div class="skeleton skeleton-text"></div>
<div class="skeleton skeleton-img"></div>
</div>
</body>
</html>
2. 代码说明
- 通用骨架类
.skeleton:所有骨架元素都要加这个类,统一基础样式和动画 - 流光动画:通过 CSS3
@keyframes控制渐变背景位移,实现丝滑滑动效果 - 定制化骨架:通过宽高、圆角、间距模拟不同内容(头像、标题、文字、图片)
- 响应式:适配移动端、PC 端,可直接嵌入 Vue/React/ 原生项目
五、效果展示
运行代码后,你会看到:
- 灰色卡片轮廓
- 流畅的白色流光动画
- 完全模拟真实列表布局
替换真实数据时,直接隐藏 / 删除骨架屏 DOM,渲染真实内容即可。
六、快速适配你的项目
1. 自定义样式
- 修改动画速度:调整
animation: 1.2s数值(越大越慢) - 修改背景色:修改
.skeleton的background - 修改流光透明度:调整
rgba(255,255,255,0.6)最后一位 - 修改尺寸:直接改宽高、圆角、边距
2. 配合 JS 切换显示 / 隐藏
js
// 数据加载完成后隐藏骨架屏
document.querySelector('.card').style.display = 'none'
// 渲染真实内容
document.querySelector('.real-content').style.display = 'block'
3. Vue/React 中使用
- Vue:用
v-if控制骨架屏和真实内容切换 - React:用
{isLoading ? <Skeleton/> : <Content/>}条件渲染
七、优势总结
✅ 零依赖:纯 HTML+CSS,无需安装任何包
✅ 轻量:代码不足 1KB,不增加项目体积
✅ 通用:原生 / Vue/React/ 小程序全适配
✅ 易改:5 分钟定制任意页面骨架
✅ 流畅:CSS 动画性能远超 JS 实现
八、写在最后
骨架屏是提升用户体验的低成本高回报方案,纯 CSS 实现既简单又实用,完全能满足中小型项目需求。