骨架屏是用灰色块模拟真实列表结构的占位方案,而非动效加载图标;它通过固定尺寸布局、伪元素渐变背景和display:none切换实现平滑渲染,避免布局跳变与闪烁。

什么是骨架屏,为什么不用 loading 图标
骨架屏不是动效加载图标,而是用灰色块模拟真实列表的结构——比如头像位置留个圆角矩形、标题占两行、描述占一行。用户感知到的是“内容正在来”,而不是“我在等”。对列表类页面(如商品列表、文章流),loading 图标容易造成布局跳变:数据一到,整个区域重绘,文字闪动、按钮错位;而骨架屏提前占位,DOM 结构稳定,后续渲染更顺滑。
关键点:
- 骨架屏必须和真实列表使用**完全一致的容器尺寸与 flex/grid 布局**
- 所有 div 宽高需用固定值或百分比(禁用 min-height 或 fit-content)
- 不要给骨架元素加 transition,否则淡出时会和真实内容叠加闪烁
- 真实列表渲染完成后,直接用 display: none 隐藏骨架层,别用 opacity: 0
纯 HTML + CSS 实现列表骨架(无 JS)
不需要框架、不依赖 JS 控制显隐,靠 class 切换即可。核心是用伪元素 + background-image 模拟渐变灰块,避免大量 div 嵌套:
对应 CSS(重点看 background-image 和 aspect-ratio):
- .skeleton-item 用 aspect-ratio: 4 / 3 固定头像比例
- 标题用两个 span 模拟多行,设 width: 80% 和 width: 60%
- 背景用 linear-gradient + blur(10px) 模拟毛玻璃灰块效果,比纯色更自然
- 整个列表加 overflow: hidden,防止骨架块在加载中被意外截断
Vue/React 中怎么控制骨架屏开关
常见错误是把骨架屏写成独立组件后,在父组件里用 v-if="!data.length" 控制——这会导致骨架屏 DOM 被销毁重建,反而加重渲染压力。正确做法是始终渲染骨架层,仅切换 visibility:
将 Markdown 文章转换为微信公众号兼容的纯 HTML 格式。当用户要求"转成微信格式"、"生成公众号文章 HTML"、"排版到微信草稿箱"、"微信粘贴格式"时触发。输出带内联样式的纯 HTML,微信编辑器可直接渲染,无需额外适配。支持标题、段落、列表、粗体、行内代码、表格、引用块、代码块、配图的完整转换。
- Vue:用
:class="{ 'is-hidden': loaded }",配合.is-hidden { display: none; } - React:用
style={{ display: loaded ? 'none' : 'block' }},避免用hidden属性(它仍会触发 layout) - 务必在 API 成功回调里才设
loaded = true,不要在.then()外层提前赋值 - 如果列表支持下拉刷新,记得在刷新开始时重置
loaded = false,否则骨架屏不会再次出现
移动端适配和性能陷阱
在 iPhone 上常出现骨架块被压缩成一条细线,或安卓低端机上动画卡顿,问题往往出在这些细节:
- height: 100vh 在 iOS Safari 中不可靠,改用 min-height: 100dvh(注意兼容性,旧版需 fallback)
- 骨架层里避免用 box-shadow,尤其多条目时,GPU 渲染开销陡增
- 不要用 @keyframes 做骨架“流动光效”,iOS 15 以下会掉帧;改用 background-position 平移渐变背景更轻量
- 如果列表项超过 20 条,骨架屏 DOM 节点数暴增,建议分页加载时只渲染当前页的骨架(比如 v-for="i in pageSize")
最易忽略的一点:骨架屏的 font-size 必须和真实列表完全一致。哪怕差 0.5px,加载后文字也会轻微“上跳”,用户会觉得页面不稳。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










