必须加 preload="auto",因浏览器默认 preload="metadata" 只加载元数据,导致全屏背景视频首帧延迟渲染;需搭配 muted、autoplay、loop、object-fit: cover、playsinline 及正确编码格式。
<video> 替代 <img> 做背景时必须加 preload="auto"
浏览器默认对 <video> 的预加载策略是 preload="metadata",只加载元数据(时长、尺寸等),不加载视频帧。全屏背景需要首帧尽快渲染,否则页面白屏或闪动。必须显式写 preload="auto",否则即使加了 autoplay 和 muted,也可能在 Chrome/Firefox 中延迟数秒才显示第一帧。
常见错误现象:video 标签已设 autoplay、muted、loop,但页面加载后黑屏 1–3 秒才出画面;或者 Safari 下完全不播放。
preload="auto" 是硬性要求,不能省略muted,否则 Chrome/Firefox 会阻止自动播放(有声音的视频需用户交互才可播)autoplay 和 loop 也必须同时存在,否则视频播完就停,露出背景色object-fit: cover 而不是 width: 100vw; height: 100vh
单纯设 width: 100vw; height: 100vh 会导致视频被拉伸变形,或上下/左右留黑边。真正适配任意屏幕比例的是 object-fit: cover —— 它像 background-size: cover 一样缩放并裁剪视频,保证铺满容器且不畸变。
使用场景:手机竖屏、桌面宽屏、MacBook Pro 16:10 屏幕都需一致效果。
立即学习“前端免费学习笔记(深入)”;
<div class="video-bg">)需设 position: fixed; top: 0; left: 0; width: 100vw; height: 100vh; z-index: -1;
<video> 自身设 width: 100%; height: 100%; object-fit: cover;
video 设 min-width 或 min-height,会破坏 object-fit 行为playsinline 才能内联播放iOS Safari 默认把 <video> 强制全屏播放(进入原生播放器),导致你的 CSS 全屏逻辑失效,页面只剩黑块或占位图。加 playsinline 属性才能让它乖乖待在网页里播放。
兼容性影响:不加该属性,iPhone/iPad 上 100% 失效;加了之后仍需配合 muted 和 autoplay,否则仍可能被静音拦截。
<video playsinline muted autoplay loop preload="auto">
canplaythrough 防白屏即使写了 preload="auto",网络慢或视频大时,首帧仍可能延迟。用户看到白屏会以为页面卡死。最稳妥的做法是先用 poster 属性设一张静态封面图,再用 JS 在视频可流畅播放时隐藏它。
容易踩的坑:直接用 display: none 隐藏 poster 会导致视频加载完成前始终显示占位图;应监听 canplaythrough 事件而非 loadeddata,后者只表示首帧加载完,canplaythrough 才代表足够缓冲、可连续播放。
<video poster="cover.jpg"> 提供与视频宽高比一致的封面图video.addEventListener('canplaythrough', () => { video.style.opacity = '1'; }),初始 CSS 设 opacity: 0
visibility: hidden,它仍占布局空间,可能影响下方内容定位