opacity + transition 失效主因是 display: none 或 visibility: hidden 中断动画;应仅改 opacity 和 pointer-events,初始值设为 opacity: 1,推荐 transition: opacity 0.25s ease-out,并在 transitionend 后设 visibility: hidden。

opacity + transition 为什么不起作用
直接给 opacity 加 transition 是对的,但常见失效是因为元素被 JS 瞬间设为 display: none,或者 CSS 中存在更高优先级的 visibility: hidden / display 覆盖。transition 只对可动画属性的**渐变过程**生效,一旦中间被强制“跳变”,动画就中断。
- 确保隐藏操作只改
opacity和pointer-events(避免点击穿透),别碰display - 如果用 JS 控制,不要写
el.style.display = 'none',而应改 class 或仅设el.style.opacity = '0' - 初始状态必须有明确的
opacity值(比如opacity: 1),不能依赖浏览器默认或继承值
transition-duration 和 timing-function 怎么选
淡出不是越慢越好,也不是一律用 ease。实际体验中,0.2s–0.3s 的 transition-duration 最自然;过长显得卡顿,过短看不出效果。timing-function 决定“淡”的节奏——ease-out 比 ease 更适合隐藏,因为它在结束前减速,视觉上更“收住”。
- 推荐写法:
transition: opacity 0.25s ease-out; - 避免用
linear:匀速变化缺乏真实感,容易显得机械 - 慎用
transition: all:可能意外触发其他属性动画(比如height、margin),导致布局抖动
隐藏后如何真正移除交互和占位
opacity: 0 只是看不见,元素还在文档流里,能响应鼠标事件、影响 tab 键顺序、占用空间。要真正“退出舞台”,得配合其他属性,但顺序和时机很关键。
- 必须等 opacity 动画完成后再设
visibility: hidden或pointer-events: none,否则动画会立即终止 - JS 中可用
transitionend事件监听:el.addEventListener('transitionend', () => { el.style.visibility = 'hidden'; }) - 如果需要完全脱离文档流(比如不占高度),得额外控制
height、overflow,但这时建议改用max-height过渡,而非opacity单独处理
兼容性与 Safari 的小毛病
现代浏览器都支持 opacity + transition,但 Safari(尤其 iOS 15 之前)对 opacity 动画的硬件加速不敏感,偶尔卡顿。另外,如果父容器有 transform(比如 translateZ(0)),某些旧版 Chrome 会干扰 opacity 过渡的渲染。
立即学习“前端免费学习笔记(深入)”;
- 加
will-change: opacity可提示浏览器提前优化(但别滥用,会增加内存开销) - Safari 下若仍有闪烁,尝试给元素加
backface-visibility: hidden - 不要在
:hover里只写opacity过渡而不设初始transition,否则首次悬停无动画


















