遮罩层必须用 position: fixed 因为需覆盖整个视口且不受滚动影响;absolute 易因父容器高度不足漏白,relative 则完全无法覆盖;可靠写法是 fixed + 0/0/100vw/100vh。

遮罩层为什么必须用 position: fixed
因为遮罩要覆盖整个可视区域,不受滚动影响。如果用 absolute,父容器没设 height: 100vh 或有 overflow: hidden,就可能漏出白边或无法撑满;用 relative 更不行——它只相对自身定位,完全失去覆盖能力。
真正可靠的写法是:position: fixed; top: 0; left: 0; width: 100vw; height: 100vh;。注意不是 100%,100% 会继承父高,而 100vh 才是视口高度,且兼容所有现代浏览器(IE9+)。
rgba() 背景的透明度控制与色值陷阱
很多人写 background: rgba(0, 0, 0, 0.5) 后发现遮罩“发灰”或“透出奇怪颜色”,其实是没意识到:rgba 的 alpha 通道作用于整个背景色,但若同时设置了 background-image 或叠加了其他半透明元素,就会产生多重叠加导致视觉过暗。
更稳妥的做法是:
- 只用
background-color: rgba(0, 0, 0, 0.6),不混用图片或渐变 - 避免在遮罩层上再加
opacity—— 它会让内部子元素(比如弹窗)也变透明,破坏可读性 - 深色遮罩推荐
rgba(0, 0, 0, 0.7),浅色遮罩用rgba(255, 255, 255, 0.85),数值不是越小越好,0.3–0.4 常常遮不住底层文字
响应式断点下遮罩层的常见失效场景
遮罩层本身不需要媒体查询就能全屏,但实际项目中容易出问题的地方在于“触发它的容器”或“被遮盖的内容”。比如:
- 移动端 Safari 中,
100vh在地址栏收起/展开时会重算,导致遮罩短暂错位——加min-height: 100vh并配合height: 100%可缓解 - 如果遮罩是通过 JS 动态插入(如
document.body.appendChild(modalOverlay)),需确保插入时机在 DOM ready 之后,否则可能因样式未加载而闪现空白 - 当页面有横向滚动(比如宽表格)时,
100vw仍只取视口宽度,遮罩右侧会被截断——此时应改用width: 100%+left: 0,并确保父级(body)无overflow-x: hidden
遮罩层与焦点管理、可访问性的隐性冲突
纯视觉遮罩不阻断键盘焦点,用户按 Tab 仍能切到背后按钮,这既危险又不符合 WCAG。解决方法不是加 tabindex="-1" 到遮罩本身(它不接收焦点),而是:
立即学习“前端免费学习笔记(深入)”;
- 遮罩显示时,给被遮盖区域加
aria-hidden="true" - 把焦点显式移到遮罩内的第一个可聚焦元素(如关闭按钮):
closeBtn.focus() - 按
Esc关闭遮罩后,焦点必须回到触发它的元素(比如原按钮),否则键盘用户会迷失 - 别忽略
prefers-reduced-motion:动画过渡(如 fade-in)在该偏好开启时应降级为无动画显示


















