video元素需设position: fixed且width/height用100vw/100dvh或min-width/min-height+object-fit,配top: 0;left: 0;z-index: -1易因祖先层叠上下文失效,应改用内容容器设position: relative;z-index: 1;object-position可微调cover裁切位置;遮罩层须pointer-events: none并确保DOM顺序在video后。

video元素必须设position: fixed + width/height显式声明
直接写width: 100%; height: 100%在position: fixed下会失效——百分比此时参考的是初始包含块(initial containing block),但它的尺寸不等于视口,尤其在有滚动或缩放的页面中极不稳定。Chrome 115+ 更是明确要求fixed定位的video必须带width和height具体值才能正确触发object-fit渲染。
正确做法是:
-
width: 100vw; height: 100dvh(dvh比vh稳,避开 iOS Safari 地址栏跳变) - 或
min-width: 100vw; min-height: 100dvh+object-fit: cover,更容错 - 必须配
top: 0; left: 0,否则fixed锚点偏移,视频只显示左上角一小块 - 删掉
inset: 0这种写法——它在部分浏览器中与object-fit配合时尺寸计算异常
z-index: -1 失效?先查祖先是否创建了新层叠上下文
z-index: -1不是“绝对垫底”,它只在当前层叠上下文内生效。一旦video的任意祖先(哪怕隔了三层)设置了transform、opacity: 0.99、filter或will-change,就会创建独立 stacking context,导致z-index: -1被截断,视频反而浮在文字上面。
排查和修复建议:
立即学习“前端免费学习笔记(深入)”;
- 用浏览器开发者工具检查
video所有父级,看 computed 样式里是否有transform或opacity < 1 - 给内容容器(如
<main>)显式加position: relative; z-index: 1,比依赖z-index: -1更可靠 - 避免给
video本身加transform: translateZ(0)或will-change: transform——除非真需要 GPU 加速,否则纯属自建陷阱 - 如需遮罩层(
<div class="overlay">),确保它和video同级,且父容器加isolation: isolate
object-fit: cover 裁切位置不对?用 object-position 微调
object-fit: cover默认从内容左上角开始覆盖,不是居中裁切。如果视频关键区域(比如人脸、logo)不在中心,很容易被裁掉——这不是 bug,是规范行为。
调整方法很简单:
- 加
object-position: center center(默认值,但显式声明更可控) - 若人脸偏下,改用
object-position: center 70%把画面往下推 - 若 logo 在右上角,可试
object-position: 90% 10% - 注意:
object-position只对cover和contain生效,fill下无效
别指望靠transform: translate()去“手动居中”——它会破坏object-fit的原始比例逻辑,还可能触发额外层叠上下文。
遮罩层挡住点击?pointer-events: none 是刚需
很多人加完半透明遮罩(background: rgba(0,0,0,0.4))后发现按钮点不了,第一反应是调z-index。其实问题在事件捕获层:遮罩层默认拦截所有鼠标事件。
解决方式非常直接:
- 给遮罩层加
pointer-events: none - 如果遮罩里还要放文字或图标,再给那些子元素单独设
pointer-events: auto - 不要用
background直接盖在video上——背景色属于video自身,无法独立控制事件;必须用独立<div>作为遮罩层 - 验证是否生效:在开发者工具中选中遮罩层,看
pointer-events是否为none,且鼠标悬停时下方元素能正常高亮
真正容易被忽略的是:遮罩层必须放在video之后、内容之前,DOM 顺序决定默认堆叠顺序,z-index只是微调手段。


















