必须用position: fixed,因其始终锚定视口四角,抗滚动、无视父容器约束;absolute会随祖先overflow/transform偏移或裁剪,relative不脱离文档流无法覆盖全屏。

必须用 position: fixed,其他定位方式在滚动、父容器约束或视口变化时都会漏白或错位。
为什么不能用 position: absolute 或 position: relative
position: absolute 会相对于最近的已定位祖先(比如某个 div)计算位置;一旦该祖先设置了 overflow: hidden、transform 或高度不足,蒙层就被裁剪或偏移。滚动时它还会跟着内容动,根本盖不全。position: relative 根本不脱离文档流,连“覆盖”都做不到——它只是挪动自身位置,不影响布局流,更不会撑满视口。
只有 position: fixed 始终锚定在视口四角,天然抗滚动、无视父容器限制。
- 常见错误现象:页面一滚动,蒙层就消失,或只盖住初始可视区顶部
- 检查方法:用 DevTools 查看蒙层元素的 computed
position和offsetParent,若显示为某个 div 而非viewport,说明被祖先干扰了
inset: 0 和 top/right/bottom/left: 0 怎么选
inset: 0 是语义更清晰、写法更紧凑的等效写法,现代浏览器(Chrome 89+、Firefox 63+、Safari 14.1+)支持良好。但它不是万能兜底——Safari 14.0 或旧版 Android WebView 不识别,会导致蒙层完全不显示。
立即学习“前端免费学习笔记(深入)”;
稳妥做法是并行声明:
.overlay {
position: fixed;
inset: 0;
top: 0; right: 0; bottom: 0; left: 0;
background-color: rgba(0, 0, 0, 0.5);
z-index: 9999;
}
- 漏写任意一边(比如只写
top: 0; left: 0)会导致蒙层缩成一个点——这是最常踩的坑 - 别用
width: 100vw; height: 100vh:iOS Safari 中vh值随地址栏收放跳变,容易底部留白;vw在有垂直滚动条时可能宽度不足
移动端滚动穿透和 iOS 视口抖动怎么防
CSS 单独解决不了。遮罩显示时,iOS Safari 仍允许底层 body 滚动,本质是 body 的 overflow 没禁用;而地址栏收放又会让视口高度突变,fixed 元素不会自动重绘,造成遮罩偏移。
- 显示遮罩时:
document.body.style.overflow = 'hidden',同时加overscroll-behavior: contain防弹性滚动透出 - 隐藏遮罩后:务必恢复
document.body.style.overflow = '',否则页面卡死 - 防抖动兜底:监听
resize和orientationchange,触发时强制重排:document.body.style.transform = 'translateZ(0)',再立刻设回none - 更稳的高度方案:用
min-height: 100dvh(Chrome 105+/Safari 16.4+ 支持),或 JS 动态设style.height = document.documentElement.clientHeight + 'px'
蒙层内内容居中为什么不能只靠 margin: auto
margin: auto 在 position: fixed 容器里对垂直方向无效,且依赖父容器明确宽高——而 fixed 元素默认尺寸是内容自适应,不是 100% 视口。
正确做法是直接在蒙层上启用 flex 布局:
.overlay {
display: flex;
justify-content: center;
align-items: center;
}
- 这样子元素(如弹窗、加载图标)才能真正居中
- 注意:
position: absolute子元素的定位参考仍是视口,不是蒙层内部——这点容易误判为 bug - 别给蒙层或其祖先加
transform、filter、will-change:这些会创建新层叠上下文,导致z-index失效,遮罩可能被导航栏或弹窗盖住
真正上线时最难缠的从来不是写法本身,而是 transform 创建的新定位上下文、z-index 被层叠上下文隔离、以及 Safari 对 dvh 和 backdrop-filter 的实现差异——这些必须用 DevTools 的 “Layers” 和 “Computed” 面板逐层验证,不能只靠样式代码猜。


















