弹窗平滑显示需同时满足三点:使用opacity+transform组合动画、transition声明必须写在默认类中、动画结束后通过transitionend事件精准清理dom。

弹窗能平滑显示,关键不是加个 transition 就完事——得选对动画属性、控制好初始状态、并且等动画结束再清理 DOM。漏掉任一环,都会变成“闪现”或“卡住”。
为什么 opacity + transform 是首选组合
只靠 display 或 visibility 切换,根本不会触发 transition;opacity 可插值、浏览器优化好,transform: scale() 不触发重排、性能稳定。两者搭配,既能淡入又能缩放,还不影响布局流。
- 错误写法:
div { display: none; } .show { display: block; transition: all 0.3s; }→ 完全没动画 - 正确路径:初始设
opacity: 0+transform: scale(0.8),再过渡到1 - 别用
transition: all——万一后续加了color或padding,会意外带出干扰动画 - 推荐写死:
transition: opacity 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94), transform 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94)
transition 必须写在默认 class 里
很多人把 transition 放在 .show 类里,结果动画只在隐藏时有、显示时直接跳——因为浏览器只对“已有过渡声明的属性变化”做插值,初始没声明,就当无动画处理。
- ❌ 错误:
.modal { opacity: 0; } .modal.show { opacity: 1; transition: opacity 0.3s; } - ✅ 正确:
.modal { opacity: 0; transform: scale(0.8); transition: opacity 0.3s, transform 0.3s; } .modal.show { opacity: 1; transform: scale(1); } - 如果用 Tailwind,必须写成:
class="transition-opacity transition-transform duration-300 ...",不能等 JS 切换 class 时才加上transition-前缀
动画结束后必须手动清理 DOM
opacity: 0 不等于元素消失——它还在文档流里,仍占位、可 focus、影响 tab 键顺序。不处理,就是个隐藏的可交互陷阱。
- 别依赖
setTimeout等固定时长删元素,页面卡顿时会提前或延后触发 - 监听
transitionend,且只响应opacity属性:el.addEventListener('transitionend', e => { if (e.propertyName === 'opacity' && getComputedStyle(el).opacity === '0') el.remove(); }); - 不要同时写
visibility: hidden和opacity: 0——前者立即生效,动画直接被截断 - 若需保留 DOM(比如复用弹窗),改用
pointer-events: none+aria-hidden="true"控制可访问性
真正难的不是写出那几行 CSS,而是确保 opacity 动画和 transform 动画同步收尾、transition 声明从不缺席、DOM 清理不靠猜时间——这三个点错一个,用户看到的就是“抖一下”或“卡半秒”。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











