
video元素用position:fixed时内容被裁切
直接给 <video> 加 position: fixed 很容易发现视频只显示左上角一小块,甚至完全看不见——因为默认尺寸是 300×150 像素,且未设置宽高,浏览器按原始尺寸渲染,不随视口拉伸。
必须显式覆盖尺寸和定位基准:
- 加
width: 100vw和height: 100vh,而非100%(百分比在 fixed 定位下相对初始包含块,不一定等于视口) - 设
top: 0; left: 0;确保锚点在左上角 - 加
object-fit: cover防止拉伸变形;若要完整显示用contain,但会留黑边
video {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
object-fit: cover;
z-index: -1;
}
z-index: -1 导致视频被其他元素遮挡
z-index: -1 确实能把视频“垫”到最底层,但它有个硬性前提:父容器不能有 transform、filter、will-change 或 opacity < 1 ——这些属性会创建新的层叠上下文,让 z-index: -1 失效,视频反而浮在内容上面。
常见踩坑场景:
立即学习“前端免费学习笔记(深入)”;
- 页面根元素(如
<body>或<div id="app">)加了transform: translateZ(0)做硬件加速 - 全局 CSS 里写了
*, *::before, *::after { opacity: 0.999; }这类“伪透明”hack - 使用了某些 UI 框架的模态框、滚动容器,内部隐式创建了层叠上下文
解决方法不是强行调高 z-index,而是移除父级干扰属性,或把 <video> 提到 <body> 直接子级。
移动端全屏视频自动播放失败
iOS Safari 和 Android Chrome 都禁止无用户交互的自动播放(尤其带声音的)。即使加了 autoplay 和 muted,也常因策略更新失效。
关键控制点:
- 必须同时加
autoplay、muted、playsinline(iOS 必需,否则强制全屏) - 部分安卓机型要求首次触碰后才允许播放,可监听
touchstart或click后调用video.play() - 避免在
DOMContentLoaded里立即play(),改用setTimeout(() => video.play(), 0)或video.load()后再播
错误示例:<video autoplay> → 缺少 muted,大概率静音失败;正确写法:<video autoplay muted playsinline>。
视频加载慢导致背景闪白或延迟渲染
大体积 MP4(尤其 1080p+)从网络加载需要时间,position: fixed 的视频不会触发懒加载,首屏可能先看到空白或 fallback 背景色。
优化方向有限但有效:
- 用
preload="metadata"替代"auto",只预加载头信息,减少首帧等待 - 服务端开启 HTTP/2 + Brotli 压缩,视频本身用 H.265(HEVC)编码(注意 Safari 支持好,Chrome 需检查版本)
- 加
poster属性提供首帧静态图,避免白屏;图片建议用 base64 内联小尺寸 JPG - 慎用
background: black做 fallback——深色背景下视频解码失败时更难察觉问题
真正难处理的是 Safari 对 object-fit: cover + position: fixed 的重绘 bug:滚动时偶发撕裂或卡顿,目前无完美解,只能接受轻微瑕疵或降级为 poster + CSS 背景渐变过渡。










