骨架屏必须服务端首包输出,与真实内容同级同数量同class;css动画须用伪元素实现;响应式用min-width媒体查询;替换时仅用opacity和transform过渡。

骨架屏 HTML 必须随服务端首包一起输出,不能靠 JS 插入
骨架屏失效的首要原因,是 HTML 结构没在首屏渲染前到达浏览器。常见错误是等 document.readyState === 'interactive' 或 DOMContentLoaded 才用 JS 动态插入 <div class="skeleton"> —— 此时白屏已发生,LCP 直接劣化。
<p>正确做法是服务端模板(如 Express、Next.js <code>loading.tsx、PHP 模板)在首次 res.write() 或 flush 阶段就输出骨架 DOM。关键点:
- 骨架节点必须与真实内容同级、同数量、同 class 层级(例如真实有 3 个
<article class="card"></article>,骨架就得有 3 个<div class="skeleton-card">) <li>禁用 <code>ob_start()等全量缓冲;Node.js 中用res.write('<div id="root"></div>')+res.flush()提前下发 - 骨架元素需设明确
width、height和overflow: hidden,否则 height 为 0 导致布局塌陷 - 父容器设
position: relative - 每个骨架子元素(如
.skeleton-avatar)只负责尺寸和圆角,不写 background 或 animation - 动画由
::before伪元素承载:.skeleton-avatar::before { content: ""; position: absolute; top: 0; left: 0; right: 0; bottom: 0; background-image: linear-gradient(...); animation: loading 1.5s infinite; } -
@keyframes loading只定义一次,background-position必须横向移动(200% 0→-200% 0),禁用opacity动画防重绘 @media (min-width: 480px) { .skeleton-title { width: 70%; background-size: 300px 100%; } }@media (min-width: 768px) { .skeleton-title { width: 50%; background-size: 500px 100%; } }@media (min-width: 1024px) { .skeleton-title { width: 40%; background-size: 600px 100%; } }- 所有骨架元素优先用
rem或vh/vw,避免固定px尺寸 - 初始状态:骨架
opacity: 1,真实内容opacity: 0; pointer-events: none; - 加载完成:给骨架加
opacity: 0; transform: translateY(-5px);,真实内容加opacity: 1; transform: none; - 两者共用同一
transition: opacity 0.3s ease, transform 0.3s ease,CSS 触发硬件加速 - 切忌在 JS 中操作
classList.add('loaded')后再用 CSS 控制显隐——hydration 错位风险极高
CSS 动画必须绑定伪元素,且仅作用于占位区域
直接给 .skeleton-title 设 animation: loading 1.5s infinite 是错的:动画会持续运行,内容加载后仍“发光”,多个节点还可能因复用动画实例而节奏不同步。
真正生效的写法是:
响应式骨架屏必须用 min-width 媒体查询,且重置 background-size
写 @media (max-width: 768px) 会导致 iPad Pro 等高 DPR 设备因 viewport 缩放后实际宽度 > 768px 却不命中规则,骨架宽高比崩坏。
使用 PptxGenJS 和 Python 解析,将结构化的 HTML/CSS 幻灯片内容转换为原生、可编辑的 PowerPoint(.pptx)演示文稿。
可靠方案是自底向上叠加:
真实内容替换时,只改 opacity 和 transform,别碰 display 或 visibility
用 display: none 隐藏骨架、再用 display: block 显示真实内容,会触发重排;用 visibility: hidden 则屏幕阅读器无法感知切换,且样式未预加载完时可能闪出原始文字。
安全过渡方式:










