最通用的遮罩层是用带半透明背景的<div>配合position和z-index实现;盖全屏用fixed,盖局部用absolute(父设relative);需避免隐式层叠上下文干扰z-index;遮罩层应设pointer-events:auto并明确宽高。

遮罩层不是靠某个叫 mask 的 HTML 标签实现的,HTML 本身没有原生遮罩标签;真正可靠、可控的遮罩层,是用一个带半透明背景的 <div> 叠在目标元素上方,配合 position 和 z-index 控制层级——这是最通用、兼容性最好、也最容易调试的做法。
遮罩层必须用 position: fixed 还是 absolute?
取决于你要盖住什么:
- 想盖住整个视口(比如全屏弹窗、加载中提示),用
position: fixed,它相对于浏览器窗口定位,滚动不移位 - 只想盖住某个局部容器(比如一个卡片内的操作区域),用
position: absolute,但父容器必须设position: relative或其他非static值,否则会往上找最近的定位祖先,容易错位 - 别用
position: static或默认值——它根本不会脱离文档流,z-index无效
z-index 不生效?大概率是层叠上下文搞错了
遮罩层没盖上去,常见原因是它和目标元素不在同一个层叠上下文里。比如父容器加了 transform、opacity < 1、filter 等,会隐式创建新层叠上下文,导致子元素的 z-index 只在内部比较,无法压过外部元素。
- 检查遮罩层父级是否意外触发了层叠上下文(用浏览器开发者工具看“Computed”里的
transform或opacity) - 确保遮罩层和被遮盖内容的最近共同祖先没有创建隔离上下文
- 如果必须用
opacity: 0.99模拟半透明,不如改用background: rgba(0,0,0,0.5),它不触发新上下文
遮罩层要阻止点击穿透,光靠 pointer-events: none 是反的
新手常误设 pointer-events: none 在遮罩层上,结果点不到遮罩层自己,反而穿透到下面——这恰恰违背了“遮罩”的本意。正确做法是:
立即学习“前端免费学习笔记(深入)”;
- 遮罩层本身需要响应事件(比如点击关闭),就保持
pointer-events: auto(默认值) - 如果只想让它挡着、不响应任何交互,才设
pointer-events: none;但此时它也不拦点击了,等价于不存在 - 真要“只挡不响应”,且底层元素不能被点,就得在遮罩层上加
pointer-events: auto+background: transparent(或极低透明度色值),再用 JS 拦截click事件并stopPropagation()
最易被忽略的一点:遮罩层的 height 和 width 必须明确撑开,否则即使 position 正确,也可能因为内容为空而高度为 0,看起来像没生效——建议统一写 top: 0; left: 0; width: 100%; height: 100%,比依赖内容更稳。



















