用 opacity 遮罩会导致子元素一同变透明,正确做法是用伪元素(如 ::before)配合 rgba 背景或 inset: 0 实现独立遮罩层,避免影响内容清晰度与交互。

用 opacity 遮罩时,子元素会一起变透明
这是最常踩的坑:opacity 作用于整个元素及其所有后代,无法只让背景变半透而文字保持清晰。比如给一个 div 设置 opacity: 0.5,里面 p、img 全都跟着发虚。
实际场景中,多数人想要的是“玻璃幕布”效果——背景蒙层半透,但上面的按钮、标题仍 100% 清晰。这时候必须把遮罩层和内容层拆成两个同级元素,或用伪元素隔离。
- 推荐做法:用
::before或::after伪元素做遮罩层,定位覆盖在容器上 - 避免写法:直接对包含文字的容器设
opacity - 若必须用
opacity,需额外给子元素设opacity: 2(无效)——别试,CSS 不支持 opacity 反向抵消
用 background-color 的 rgba 值更可控
background-color: rgba(0, 0, 0, 0.6) 是真正只影响背景的半透方案。alpha 通道只作用于该颜色本身,不传染子元素,也不影响边框、阴影等其他属性。
注意几个关键点:
立即学习“前端免费学习笔记(深入)”;
- 必须用
rgba()或hsla(),不能用十六进制加 alpha(如#0008虽然部分浏览器支持,但兼容性差且不易读) - 如果父容器没设
position: relative,而遮罩层用了position: absolute,它会相对于最近的定位祖先定位,容易跑偏 - 纯色遮罩建议搭配
backdrop-filter: blur(4px)(慎用,iOS Safari 对backdrop-filter支持有限)
遮罩层要撑满容器的三种可靠写法
遮罩不填满,就会漏出底层内容。常见错误是只设 width: 100%; height: 100%,但没考虑盒模型或父容器高度未定义。
- 方案一(推荐):伪元素 +
inset: 0——div::before { content: ""; position: absolute; inset: 0; background: rgba(0,0,0,0.5); } - 方案二:绝对定位 + 四方位全设
top/bottom/left/right: 0,兼容性更好(IE11 也支持) - 方案三:用
background直接画在容器上,但仅适用于纯色遮罩且无需独立交互(比如不能单独给遮罩加点击事件)
遮罩层需要交互时,记得处理 pointer-events
如果遮罩层盖在按钮上,又想点击穿透到底层按钮,得加 pointer-events: none;如果遮罩层自己要响应点击(比如关闭弹窗),就得确保它在 DOM 中可捕获事件,且 z-index 足够高。
- 默认情况下,
position: absolute的遮罩层会拦截鼠标事件 -
pointer-events: none会让它彻底“隐形”于事件系统,连:hover都失效 - 若遮罩含图标或关闭按钮,应把可点击部分抽成子元素,并设
pointer-events: auto
content: "" 忘写会导致遮罩消失,这种低级错误调试起来反而最耗时间。










