根本原因是浏览器对object-fit、aspect-ratio和视口缩放处理不一致;必须设object-fit:cover于video标签,且同时满足muted、autoplay、playsinline三属性,否则iOS/Safari拒绝自动播放。

为什么 <video> 全屏后总有黑边或跳变
根本原因不是代码写错,而是浏览器对 object-fit、aspect-ratio 和视口缩放的处理不一致。默认情况下,<video> 会按原始宽高比拉伸,一旦视频分辨率和屏幕不匹配(比如 16:9 视频在 21:9 屏幕上),就会出现上下/左右黑边;而用 width: 100vw; height: 100vh 强制拉伸又会导致画面畸变或首帧闪动。
关键不是“铺满”,而是“裁切+居中+静音自动播放”——这三点缺一不可。
-
object-fit: cover必须设在<video>上,不能只设在父容器 - 必须添加
muted autoplay playsinline属性,否则 iOS/Safari 会拒绝自动播放 - 避免用
position: fixed套一层 wrapper,它可能触发合成层异常,导致首帧卡顿
最简可用的 HTML 结构(无 JS、无 CSS 外链)
下面这段代码复制即用,已通过 Chrome 120+、Safari 17+、Edge 122 测试,支持桌面和主流移动端:
<video autoplay muted loop playsinline preload="auto" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; object-fit: cover; z-index: -1;"> <source src="bg.mp4" type="video/mp4"> <source src="bg.webm" type="video/webm"> </video> <div style="position: relative; z-index: 1;"> <!-- 你的内容放这里 --> <h1>Hello World</h1> </div>
注意:preload="auto" 能提升首帧加载速度,但某些安卓 WebView 会忽略它;如果首帧延迟明显,可改用 preload="metadata" 并配合 poster 占位图。
立即学习“前端免费学习笔记(深入)”;
poster 和 fallback 图片怎么配才不闪
视频加载前的空白期,浏览器会先渲染 poster,等第一帧就绪后立刻切换——这个切换过程若控制不好,就会“闪一下”。常见错误是把 poster 设为缩略图,尺寸不对,导致重绘。
-
poster图片分辨率必须和视频原始分辨率一致(例如视频是 3840×2160,poster 就得是同尺寸) - 格式优先选
.jpg(体积小、解码快),避免.png(带 alpha 通道会多一次合成) - 不要依赖 CSS 背景图做 fallback,
<video>的poster是唯一可控的加载中间态
示例写法:<video poster="bg-poster.jpg" ...>,且确保该图片已压缩到 100KB 以内。
移动端自动播放被拦截?检查这三个硬性条件
iOS Safari 和部分安卓浏览器要求同时满足:静音(muted)、用户手势触发过(首次访问需点击/触摸)、playsinline。但页面一打开就要播,没法等用户点——所以得绕过“首次交互”限制。
- 必须加
muted,哪怕你后续用 JS 解除静音,也得先带上 -
playsinline不可省略,否则 iOS 会全屏跳转播放器 - 某些安卓厂商浏览器(如华为、小米)要求
autoplay后紧跟load()调用,可在<video>后加一行:<script>document.querySelector('video').load()</script>
真正容易被忽略的是:视频文件本身不能有音频轨。哪怕静音了,只要 MP4 文件里包含音频流,部分浏览器仍会拒绝自动播放。用 ffmpeg -an 去掉音频再压一次。



















