骨架屏样式必须内联,否则ssr/首屏直出时会因css加载延迟导致闪白或错位;需用直接写入,精简规则、避免变量、加!important,并注意移动端safari兼容性。

骨架屏必须内联,否则 SSR 或首屏直出时会闪白或错位——CSS 文件加载有延迟,而骨架需要在 HTML 解析完成瞬间就渲染出来。
为什么骨架屏样式不能外链或用 @import
服务端渲染(SSR)或静态生成(SSG)页面时,HTML 是直接吐给浏览器的。如果骨架类(如 .skeleton)的样式放在外部 CSS 文件里,浏览器得先下载、解析、注入样式表,才能渲染占位结构——这中间可能有 100–300ms 空白,用户看到的就是白屏或布局抖动。
- 外链 CSS 无法保证与 HTML 同步到达,尤其在弱网下更明显
-
@import会阻塞并串行加载,比<link>更慢 - 框架如 Next.js / Nuxt 的
或useHead默认不内联,需手动配置script: { strategy: 'beforeRender' }或类似机制
怎样写最小可行的内联骨架样式
只保留最核心的类和动画,避免冗余规则。重点是:结构尺寸、渐变背景、扫光动画、显隐控制。不要用 CSS 变量或复杂嵌套——它们在内联时难维护且部分旧浏览器不支持。
- 用
<style></style>标签直接写在里,或通过构建工具(如 webpack 的html-webpack-plugin)注入 - 关键类必须带
!important(仅限内联场景),防止被后续外链 CSS 覆盖 - 动画名用简短唯一值(如
sh),避免命名冲突 - 示例内联片段:
<style>
@keyframes sh { from { background-position: -200px 0; } to { background-position: 200px 0; } }
.skeleton {
background-color: #f0f0f0;
background-image: linear-gradient(90deg, transparent, rgba(255,255,255,0.2), transparent);
background-size: 300px 100%;
background-position: -200px 0;
background-repeat: no-repeat;
animation: sh 1.5s infinite;
}
.skeleton-avatar { width: 40px; height: 40px; border-radius: 50%; overflow: hidden; }
.skeleton-title { width: 60%; height: 20px; margin-top: 12px; border-radius: 4px; }
</style>
内联后如何安全切换真实内容
骨架 DOM 必须存在且样式已生效,真实内容才可替换。不能靠 JS 动态插入 <style></style>,也不能等 DOMContentLoaded 再挂载骨架——那时已经晚了。
- 真实内容容器与骨架容器应共用同一 DOM 节点(如都用
<div id="content">),用 <code>v-if(Vue)或{isLoading ? <skeleton></skeleton> : <realcontent></realcontent>}(React)控制分支 - 切勿用
display: none隐藏骨架再显示内容——它破坏文档流,导致 SSR hydration 不一致 - 推荐用
opacity: 0+visibility: hidden初始隐藏真实内容,加载完设为opacity: 1+visibility: visible,配合transition: opacity 0.2s - 失败回退时,保留骨架并加一层
<div class="error-tip">加载失败</div>,别删 DOM -
background-size必须用px,禁用rem、vw、%(Safari 会降级为默认值) -
background-position的初始值必须带单位(-200px 0,不能写-200 0) - 所有骨架容器必须显式设
overflow: hidden,否则圆角区域扫光溢出,露出白边 - 图片占位必须用
aspect-ratio(Chrome 88+/Safari 15.4+ 支持),别写死height;若需兼容旧版 iOS,改用 padding-bottom 百分比 hack
移动端内联骨架的兼容性雷区
iOS Safari 对内联样式本身没限制,但对其中某些值极度敏感。写错单位或顺序,整段动画就静止不动。
内联不是“把所有 CSS 塞进去”,而是精准控制哪几行样式必须抢在 HTML 解析完就生效。多写一行无用规则,就多一分首屏抖动风险。











