真正可控的遮罩必须将背景层与内容层物理隔离,因opacity是继承式透明,会导致子元素强制变淡且无法恢复;应优先使用rgba()设置背景透明、伪元素+inset:0构建遮罩层,并注意定位、层级和移动端兼容性。

直接用 opacity 给容器设透明度,子元素(文字、按钮、图片)一定会跟着变模糊——这不是遮罩,是“全息失焦”。真正可控的遮罩必须把背景层和内容层物理隔离。
为什么不能对整个容器用 opacity
因为 opacity 是继承式透明:父元素设 opacity: 0.5,所有后代元素(包括 p、button、img)的 opacity 都被强制乘以 0.5,无法单独恢复。视觉上文字发虚、点击区域响应变弱,甚至某些浏览器会降低事件捕获优先级。
- 常见错误现象:
div.overlay { opacity: 0.4; }后面放一个,按钮文字看不清,hover 效果也变淡 - 想“反向抵消”?写
button { opacity: 2 }无效——CSS 不支持 opacity > 1 - 唯一合法用途:整页淡入/淡出动画(无交互内容),或临时禁用整块 UI 区域
background-color: rgba() 是更安全的半透方案
它只作用于背景色本身,不影响边框、阴影、子元素颜色或事件穿透性。alpha 值在 0–1 之间,推荐用 rgba(0, 0, 0, 0.6) 或 hsla(0, 0%, 0%, 0.6)(后者在暗色模式下更稳定)。
- 别混用:
background: rgba(0,0,0,0.5)和background-color: #0008冲突,后者会被前者覆盖 - 十六进制 alpha(如
#0008)在 Safari ≤15 和部分安卓 WebView 中渲染异常,现代项目建议优先用rgba() - 如果遮罩层要加
border或box-shadow,它们不会受rgba()影响,可独立控制样式
伪元素 + inset: 0 是最可靠的遮罩层构建方式
用 ::before 或 ::after 创建一个同级遮罩层,既不污染 DOM 结构,又能完全解耦视觉与交互。
- 关键写法:
.container::before { content: ""; position: absolute; inset: 0; background: rgba(0,0,0,0.5); } - 兼容性兜底:Safari ≤14 不支持
inset,改用top: 0; right: 0; bottom: 0; left: 0; - 父容器必须设
position: relative,否则伪元素会相对于body定位,容易跑偏 - 若需点击穿透(比如遮罩只做视觉提示),加
pointer-events: none;若需自己响应点击(如关闭弹窗),保持默认auto并确保z-index足够高
全屏遮罩必须用 position: fixed,不是 absolute
页面一滚动,position: absolute 的遮罩就跟着动,立刻露底。只有 fixed 锚定视口,才能稳稳盖住整个屏幕。
- 正确尺寸写法:
top: 0; right: 0; bottom: 0; left: 0;(比width: 100vw; height: 100vh更稳,避开滚动条宽度计算误差) - 记得同步处理 body 滚动:
document.body.style.overflow = 'hidden'显示时加,隐藏时还原(存原始值,别硬写'auto') - 移动端微信内置浏览器对
pointer-events: none在伪元素上的支持不一致,真机测试必做
真正卡住人的从来不是怎么写那行 rgba(),而是定位参照物是否明确、层叠上下文是否被意外截断、以及移动端滚动穿透是否被彻底堵死——这些细节不验证,上线后问题一定出现在凌晨三点。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











