只用 opacity 会导致点击穿透,因为 opacity 仅改变透明度而不影响元素的可交互性与文档流占据;需配合 visibility: hidden 或 display: none 才能彻底禁用交互。

为什么只用 opacity 会导致点击穿透?
单纯靠 opacity: 0 隐藏抽屉时,元素仍占据文档流、响应事件——用户点到“看不见”的菜单项上,照样触发链接跳转或按钮回调。这不是视觉bug,是 CSS 渲染机制决定的:opacity 只影响透明度,不改变可交互性。
必须搭配 visibility: hidden(隐藏且不可交互)或更彻底的 display: none(完全脱离渲染树)。但后者无法配合 transition 动画,所以标准解法是:用 visibility 控制交互开关,用 opacity 控制淡入淡出效果。
-
visibility: hidden+opacity: 0→ 完全不可见、不可点、占位(若需保持布局稳定可选) -
visibility: hidden+opacity: 0+pointer-events: none→ 更保险,双重屏蔽交互 - 动画开始前先设
visibility: visible,再触发动画;动画结束帧设visibility: hidden(不能和opacity: 0同时设在起始状态)
transition 要写在哪一层?为什么不能只写在 opacity 上?
抽屉通常还伴随位移(比如从 left: -100% 滑入),只过渡 opacity 会显得“悬空出现”。真实体验需要 opacity + transform 同步过渡,且两者必须写在同一 transition 声明里,否则浏览器可能触发两次重绘,造成卡顿或不同步。
推荐写法:transition: opacity 0.3s ease, transform 0.3s ease;。注意不要拆成两条 transition,CSS 会以最后一条覆盖前面的。
- 避免用
left/right做位移——会触发 layout,性能差;优先用transform: translateX() - 过渡时间统一用
0.3s左右,短于 0.2s 显突兀,长于 0.4s 显拖沓 - 务必加
will-change: opacity, transform(仅对频繁开闭的抽屉)提示浏览器优化渲染路径
如何用 class 控制开/关状态而不依赖 JS 切换多个样式?
把所有动画逻辑收束到两个 class 上:drawer--open 和 drawer--closed,用 JS 单次切换 class 名即可驱动整套行为。关键在于初始态和目标态的样式要“对称”:
`.drawer {
position: fixed;
top: 0;
left: 0;
width: 300px;
height: 100%;
background: #fff;
transform: translateX(-100%);
opacity: 0;
visibility: hidden;
transition: opacity 0.3s ease, transform 0.3s ease;
}
.drawer--open {
transform: translateX(0);
opacity: 1;
visibility: visible;
}
.drawer--closed {
transform: translateX(-100%);
opacity: 0;
visibility: hidden;
}`
- 初始状态(
.drawer)就设好visibility: hidden和opacity: 0,避免页面加载时闪现 -
.drawer--open只负责“终态”,不重复声明 transition —— 动画由基础类承载 - JS 里只需
el.classList.toggle('drawer--open'),无需手动操作 style
移动端真机上为什么动画卡顿或闪一下?
常见原因不是代码逻辑错,而是渲染层没激活。iOS Safari 和部分安卓 WebView 对非合成层动画优化很弱,opacity 和 transform 本该走 GPU 合成,但若父容器有 overflow: hidden 或 backface-visibility: hidden 缺失,可能降级为 CPU 渲染。
- 给抽屉容器加
backface-visibility: hidden和perspective: 1000强制开启硬件加速 - 确保遮罩层(overlay)也用
opacity+visibility,别用background: rgba()配合display: none切换——rgba 不触发合成,且 display 切换无过渡 - 真机调试时打开 Safari 开发者工具 → “Timelines” 面板,看动画帧率是否稳定在 60fps;若掉帧,检查是否有 layout / paint 事件高频触发
最易被忽略的是:动画结束后没清理 transform 值。抽屉关闭后仍保留 transform: translateX(-100%) 是 OK 的,但若 JS 误将 style.transform 设为空字符串,会强制回退到初始值(可能触发 layout),导致下一次打开时位置错乱或闪动。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











