蒙版opacity动画失效是因初始用了display:none,应改用opacity+visibility+pointer-events控制显隐;遮不住固定定位元素是z-index未对齐,需建立层级契约:蒙版z-index设100,被遮盖元素z-index必须小于100。

点击按钮触发蒙版显示时,opacity 动画不生效
直接写 opacity: 0 → opacity: 0.7 并加 transition,但蒙版仍“啪”一下弹出来,没有渐变——大概率是初始状态用了 display: none。这个属性会让元素彻底脱离渲染流,transition 对它无效。
正确做法是让蒙版始终在 DOM 中、用 opacity 和 visibility 配合控制显隐:
-
opacity: 0+visibility: hidden+pointer-events: none作为默认隐藏态 - 显示时只改
opacity: 0.7和visibility: visible,pointer-events: auto -
transition: opacity 0.3s ease, visibility 0.3s(注意:visibility 本身不可动画,但延迟触发可见性切换可避免点击穿透)
蒙版遮不住固定定位的弹窗或导航栏
常见现象:蒙版出来了,但顶部导航栏、右下角悬浮按钮依然 clickable 或 visible——z-index 没对齐。
关键不是堆数字,而是建立清晰的层级契约:
- 蒙版用
position: fixed,z-index 设为100(不要用 9999 这种魔数) - 所有需被遮盖的 UI 元素(如 header、aside、footer)z-index 必须 100
- 弹窗本身 z-index 设为
101,且必须比蒙版高一级,不能靠 JS 动态算 - 检查是否父容器有
transform、will-change或filter——这些会创建新的 stacking context,导致 z-index 失效
点击蒙版空白处关闭时,误触底层按钮
用户点蒙版想关弹窗,结果点了蒙版下面的 <button></button>,触发了其他逻辑——这是事件冒泡没截住。
解决方案要兼顾功能与可访问性:
- 蒙版元素绑定
click事件,内部调用event.stopPropagation() - 但关闭逻辑应作用于蒙版自身(比如
event.target === overlayEl),而非监听整个区域 - 额外加一层防御:给蒙版设
pointer-events: auto,弹窗内容区设pointer-events: auto,其余区域保持pointer-events: none(更精准) - 键盘用户按
Esc关闭时,确保焦点回到触发按钮,而不是丢失在页面某处
移动端 Safari 上蒙版滚动穿透问题
iOS Safari 有个经典 bug:蒙版显示后,手指在蒙版上滑动,背景页面仍会跟着滚——视觉上像“穿模”。
这不是 CSS 能单独解决的,必须配合 JS 控制 body 滚动锁:
- 显示蒙版时,记录当前
document.body.scrollTop,然后设body { position: fixed; top: -scrollTop; width: 100%; } - 隐藏蒙版时恢复
body { position: static; }并重置scrollTop - 别用
overflow: hidden—— 它在 iOS 上有兼容性问题,且可能影响键盘弹出 - 如果页面已有自定义滚动容器(如
.scroll-container),锁的是那个容器,不是body
渐隐效果容易被当成“锦上添花”,但实际中 opacity 动画卡顿、z-index 错乱、滚动穿透、键盘焦点丢失,任意一个没处理好,都会让用户觉得“这弹窗很蠢”。真正优雅,是藏在交互细节里的克制和确定性。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











