骨架屏需精准撑开布局、避免闪抖和可访问性问题,关键在设置尺寸、合理动画、正确显隐时机及防字体闪动。

骨架屏不是“加个 loading 动画”就能凑合的,它必须在真实内容还没来时,就准确撑开布局、不闪、不抖、不影响可访问性。做错一步,用户看到的可能是白屏、文字跳动、或屏幕阅读器读出一堆空 div。
为什么 skeleton 元素一渲染就塌掉、文字挤成一团
90% 是因为没设 width 和 height(或 aspect-ratio),只靠 background-color 是撑不开流式布局的。骨架元素没有尺寸,浏览器就按 0×0 渲染,后续真实内容插入时必然重排。
- 图片占位必须用
aspect-ratio: 16 / 9(现代浏览器)或padding-top: 56.25%+position: relative+ 子元素position: absolute保比例 - 文字行占位必须用
line-height × 行数设定高度,禁用height: 100%(父容器无高时失效) - 所有骨架块都要加
overflow: hidden,否则渐变动画会溢出圆角边界 - 禁用
::before/::after插入文字或符号——屏幕阅读器会误读;用纯背景色 + 渐变即可
background-position 动画比 opacity/transform 更稳
用 opacity 或 transform: translateX() 做骨架流动效果,在低配设备上容易掉帧;而仅靠 background-position 横向移动,是 GPU 合成友好的动画方式,且不触发重绘。
- 动画只写
@keyframes loading { 0% { background-position: -200% 0; } 100% { background-position: 200% 0; } } - 配合
background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%)+background-size: 200% 100% - 避免用
animation: loading 2s infinite ease-in-out——ease-in-out会让光效停顿感明显,改用linear - 低配设备需加
@media (prefers-reduced-motion: reduce) { animation: none; }兜底
Vue/React 中骨架显隐时机总出错,根本原因是 JS 太晚
等 mounted 或 useEffect 才显示骨架,此时 JS 还没执行完,用户已看到白屏。骨架必须“比 JS 更早出现”——它得在 HTML 解析阶段就存在。
将 Markdown 文章转换为微信公众号兼容的纯 HTML 格式。当用户要求"转成微信格式"、"生成公众号文章 HTML"、"排版到微信草稿箱"、"微信粘贴格式"时触发。输出带内联样式的纯 HTML,微信编辑器可直接渲染,无需额外适配。支持标题、段落、列表、粗体、行内代码、表格、引用块、代码块、配图的完整转换。
立即学习“前端免费学习笔记(深入)”;
- Vue:初始
loading: true必须在setup()顶层声明,不能延迟到onMounted里才赋值 - React:用
useState(true)初始化,且请求发起后立即setLoading(true),而不是等接口返回才设 - SSR 场景下,服务端已吐出真实 HTML,客户端 hydration 时若仍显示骨架,会闪一下——需加判断:
document.readyState === 'complete'时跳过初始骨架 - 千万别用
v-show或visibility: hidden控制显隐,它们仍参与布局计算,SSR 时 hydration 会错位
无限滚动中骨架接续卡顿、漏加载、重复请求
滚动到底才触发加载,用户已经看到空白了;手动监听 scroll 事件又容易高频触发、误判、卡顿。关键不是“滚到哪”,而是“快到哪”就该预热。
- 用
IntersectionObserver监听页尾占位符(如<div id="infinite-trigger"></div>),比手动算位置更稳定、不卡顿 - 把触发阈值设为
{ rootMargin: '200px' },即距离底部还有 200px 就开始加载,留出网络与渲染缓冲 - 加防抖:一次加载中,忽略后续触发;加载完再重新
observe,避免重复请求 - 服务端必须支持分页参数(如
?page=2&size=10),且返回数据带hasMore: true/false,前端据此决定是否继续挂载 observer
最易被忽略的是字体闪动:骨架屏消失瞬间,真实文字加载可能触发 FOIT/FOUT;还有 SSR 下 DOM 结构不一致导致 hydration 错位——这两处一旦出问题,骨架屏反而比空白页更伤体验。


















