全屏 loading 遮罩应使用 fixed 定位、vw/vh 单位和足够 z-index,避免 absolute 和 % 单位;推荐 JS 动态插入 body 并监听 DOMContentLoaded;动画优先 CSS @keyframes,慎用 GIF 和 innerHTML。

全屏 loading 遮罩不需要 JS 也能实现,但纯 CSS 方案在 Safari 和旧版 Edge 中有渲染延迟或 z-index 失效问题;真实项目里推荐用 document.body 动态插入 + pointer-events: none 控制交互,而不是依赖 :root 或 html 全局覆盖。
遮罩层必须用 fixed 定位,不能用 absolute
absolute 会相对于最近的 position: relative 父容器定位,一旦页面有滚动或嵌套布局,遮罩就可能只盖住局部。fixed 才能真正脱离文档流、覆盖整个视口。
- 必须设置
top: 0; left: 0; width: 100vw; height: 100vh;(注意是vw/vh,不是%,避免父容器 padding 影响) - 加
z-index: 9999不够——要确认它没被其他transform或will-change元素创建新层叠上下文而截断 - Safari 15.4+ 对
fixed在overflow: hidden的父元素中支持异常,此时需额外加transform: translateZ(0)强制提升图层
loading 动画别用 GIF,优先用 CSS @keyframes
GIF 体积大、无法控制暂停/颜色/尺寸,且在页面未完全加载时可能滞后显示。CSS 动画可内联、可复用、支持 prefers-reduced-motion 降级。
- 基础旋转:用
@keyframes spin { 100% { transform: rotate(360deg); } }+animation: spin 1s linear infinite; - 避免在遮罩上直接写
animation-delay——遮罩本身应立即出现,动画延迟由 JS 控制显隐时机更可控 - 如果用 SVG
<circle>实现环形加载,务必设display: block,否则 inline SVG 在部分安卓 WebView 中会塌陷
JS 插入遮罩时,要等 DOM ready 后再操作 document.body
在 <head> 里执行 document.body.appendChild() 会报错,因为 body 还不存在;但等 window.onload 又太晚——图片、字体等资源加载完才触发,用户已看到白屏。
立即学习“前端免费学习笔记(深入)”;
- 正确时机是
DOMContentLoaded事件,或把 script 放在</body>前 - 遮罩元素建议用
document.createElement('div')创建,而非 innerHTML 拼接,避免 XSS 风险(哪怕内容静态) - 移除遮罩时用
element.remove(),别用element.style.display = 'none'——残留 DOM 节点仍会响应鼠标事件,尤其当遮罩含input时可能意外聚焦
最易被忽略的是移动端横竖屏切换:100vh 在 iOS Safari 地址栏收起/展开时会跳变,导致遮罩高度错位。真要兼容,得监听 resize 并用 document.documentElement.clientHeight 动态重设高度——但多数场景下,加一句 height: 100% + min-height: 100vh 就够用。



















