用video实现响应式视频背景必须用position: fixed+object-fit: cover+muted autoplay playsinline,否则会黑边、变形、不播或层级错乱;width: 100vw/100vh因视口变化和文档流干扰不可靠。

video 标签本身不支持“在线运行即全屏背景”,必须配合 position: fixed、object-fit: cover 和强制静音策略,否则在 Chrome/Safari/iOS 上大概率黑屏卡首帧或被拦截。
为什么直接写 width: 100vw; height: 100vh; 会失败
浏览器默认按原始宽高比缩放视频,不是拉伸——所以即使尺寸设满,也会留上下/左右黑边,或内容被压扁变形。更糟的是:100vh 在移动端受地址栏显隐影响,滚动时视频突然跳动或裁切;100vw 还会把滚动条宽度算进去,导致横向溢出。
真正可靠的做法是:
- 用
position: fixed; top: 0; left: 0; width: 100%; height: 100%;锚定视口,不随滚动偏移 - 父容器(如
<div class="bg-video">)设 <code>z-index: -1,避免遮挡后续内容 -
video元素自身加object-fit: cover;,保持比例、裁切溢出部分 - 禁用
min-width/min-height混搭写法——它在长页面中会导致视频只覆盖首屏,而非“始终全屏” -
autoplay(HTML 属性,不是 JS 的play()) -
muted(静音,不是volume="0") -
loop(否则播完停在黑屏) -
playsinline(iOS Safari 必须,否则强制跳全屏) - 视频源优先用 MP4(H.264 + AAC),再补一个 WebM(VP9)作兜底,单格式等于放弃 Firefox 或旧 Edge
-
preload设为"metadata"而非"auto":只读时长、宽高信息,够object-fit计算,又不预载画面帧,减少弱网卡顿 - 监听
error事件,出错时用 CSS fallback:video.addEventListener('error', () => { document.body.style.background = 'url(fallback.jpg) center/cover no-repeat'; }); - 加
@media (prefers-reduced-motion: reduce)关掉视频,对无障碍友好 - 给
video加pointer-events: none; - 所有可点击内容(CTA 按钮、导航、文字)必须和
video同级,且z-index明确高于它(比如z-index: 10) - 别把按钮塞进
video标签内部——那会继承pointer-events: none,永远点不到
autoplay 不生效?检查这四个硬性属性
现代浏览器(Chrome 70+、Safari 12.1+、Edge 79+)全部强制要求:非用户手势触发的自动播放,必须同时满足以下条件,缺一不可:
额外建议加 webkit-playsinline(旧版 iOS 兼容),以及 poster="cover.jpg" 防止加载过程闪黑。
移动端适配和降级处理不能省
iOS 和部分安卓机型(如小米、华为 EMUI)对视频加载更敏感,容易卡在首帧不动。常见应对点:
pointer-events: none 是交互层的关键开关
默认 video 会捕获鼠标滚轮、点击等事件,导致文字按钮点不了、滚动被吞、甚至误触发快进。解决方式很直接:
最易忽略的是层级顺序:如果页面有其他 position: fixed 元素(比如顶部导航栏),它们的 z-index 必须比视频容器高,否则会被盖住。固定定位元素的堆叠上下文是独立的,不能只看数值大小,要看父容器是否新建了上下文。











