骨架屏DOM结构必须撑开真实布局空间,90%塌陷因未设width/height或aspect-ratio;需用line-height×行数设文字高度、aspect-ratio保图片比例、overflow:hidden防动画溢出,禁用img/svg,确保可访问性与精准替换。

骨架屏 DOM 结构必须撑开真实布局空间
骨架屏一渲染就塌掉、文字挤成一团,90% 是因为没设 width 和 height(或 aspect-ratio),只靠 background-color 是撑不开流式布局的。浏览器把空 div 当作 0×0 渲染,后续真实内容插入必然重排、闪抖。
- 图片占位必须用
aspect-ratio: 16 / 9(现代)或padding-top: 56.25%+position: relative+ 子元素position: absolute保比例 - 文字行占位必须用
line-height × 行数设定高度,禁用height: 100%(父容器无高时失效) - 所有骨架块都要加
overflow: hidden,否则渐变动画会溢出圆角边界 - 避免在骨架结构里嵌套
或——它们会触发资源加载或渲染阻塞
HTML 中怎么写骨架结构才不被读屏器误读
骨架元素不带文本、不设 aria-label,但若用了 ::before/::after 插入伪内容(比如 content: "loading"),屏幕阅读器会误读为空白节点+冗余字符串,破坏可访问性。
- 所有骨架元素必须是纯视觉占位:仅用
background+ 尺寸 + 圆角,不依赖文字、图标、alt或aria-*属性 - 禁止在骨架结构中使用
、、等会触发加载或解析的标签 - 骨架区域整体建议包裹在
role="region"+aria-busy="true",但内部子元素不要重复加aria-属性 - 加载完成移除骨架时,务必同步销毁 DOM 节点(
element.remove()),而非仅display: none—— 否则动画仍在后台跑,长期驻留影响页签性能
无限滚动中骨架结构如何与真实列表对齐
无限滚动下骨架接续卡顿、漏加载、DOM 替换后状态丢失,根本原因是骨架和真实内容的结构、class、层级不一致。框架 hydration 或手动替换时,只要一个 class 名拼错或嵌套顺序不同,就会导致 focus 断掉、第三方插件未重初始化、Vue/React 组件状态清空。
- 骨架项必须和真实列表项 DOM 结构严格对齐:同级元素数量、class 名、属性名(如
data-id)、甚至注释位置都应一致 - 推荐用
+replaceWith()替换整块,而不是innerHTML = ''再拼字符串 —— 后者会丢事件监听、表单值、滚动位置 - 页尾触发占位符(如
)必须独立于骨架列表之外,且不参与骨架动画,否则 IntersectionObserver 会误判可见性 - SSR 场景下服务端已吐出真实 HTML,客户端 hydration 时若仍显示骨架,会闪一下 —— 需判断
document.readyState === 'complete'后跳过初始骨架
为什么不能用 v-show 或 visibility: hidden 控制骨架显隐
v-show(Vue)或 visibility: hidden 只是隐藏元素,仍参与布局计算、占用文档流空间,且 SSR 时 hydration 容易错位。更糟的是,它让骨架节点持续存在于 DOM 中,@keyframes 动画照常运行,长期驻留拖慢页签性能。
- 正确做法是数据请求发起后立即渲染骨架结构;接口返回成功后,用
element.remove()或parent.replaceChild(newNode, oldNode)彻底卸载 - 若需保留骨架节点用于复用(如分页场景),至少要在移除前清除动画:
el.style.animation = 'none',再el.remove() - 千万别用
opacity: 0+pointer-events: none模拟隐藏 —— 它不释放内存,也不阻止动画消耗 GPU - 深色模式适配必须用 CSS custom property(如
--skeleton-bg: #f0f0f0),而非硬编码颜色值,否则主题切换时骨架色不会同步更新
骨架屏不是“加个 loading 动画”就能凑合的事,它本质是一套精确到像素的占位契约:尺寸对、结构对、时机对、销毁也得对。最容易被忽略的,是动画销毁和 DOM 卸载这最后一步 —— 看似微小,但在单页应用反复进出同一页面时,就是内存泄漏和卡顿的源头。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











