最轻量且兼容性最好的淡入淡出方案是用 opacity 配合 transition;JavaScript 仅在需动态触发或逻辑耦合时介入,CSS transition 因声明式、性能好、可优化而成为首选。

直接用 opacity 配合 transition 是最轻量、兼容性最好、也最容易控制的方案;JavaScript 仅在需要动态触发或与逻辑强耦合时介入,别为了“炫技”绕开 CSS 做动画。
用 CSS transition 实现可控的淡入淡出
这是绝大多数场景的首选:声明式、性能好(GPU 加速)、可被浏览器优化。关键不是写多少代码,而是把触发时机和状态管理清楚。
- 元素初始状态设为
opacity: 0; visibility: hidden;,淡入时改为opacity: 1; visibility: visible;,visibility防止占位空白影响布局 - 必须在要过渡的元素上加
transition: opacity 0.3s ease, visibility 0.3s;—— 注意visibility本身不支持缓动,但加时长能让它和 opacity 同步切换 - 不要用
display: none替代visibility,因为display无法过渡,会导致瞬间消失/出现 - 如果淡入后要响应点击,确保
pointer-events: none;只在opacity: 0时设置,否则鼠标会穿透
用 element.animate() 做更灵活的淡入淡出
当需要暂停、反转、动态调整时长或链式执行多个动画,animate() 比 class 切换更直接。但它不自动处理显示/隐藏逻辑,得自己补。
- 淡入示例:
el.animate([{ opacity: 0 }, { opacity: 1 }], { duration: 300, easing: 'ease-in-out' }); - 动画结束后记得手动设置最终状态:
el.style.opacity = '1'; el.style.visibility = 'visible';,否则动画一结束就回退 - 想淡出并移除元素?不能只靠动画,得监听
animationend事件再调用el.remove()或el.style.display = 'none' - 注意 Safari 对
animate()的兼容性:iOS 13.4+、macOS 10.15.4+ 才稳定支持,老版本需降级到 CSS transition
用 JavaScript 控制 class 切换来解耦样式与逻辑
适合组件化开发或需要批量操作多个元素的场景。核心是让 JS 只管“要不要显示”,CSS 管“怎么显示”。
立即学习“Java免费学习笔记(深入)”;
- 定义两个 class:
.fade-in(含opacity: 1; visibility: visible;)和.fade-out(含opacity: 0; visibility: hidden;),都带transition - JS 中用
el.classList.add('fade-in')触发淡入,用el.classList.replace('fade-in', 'fade-out')切换淡出 - 避免同时 add/remove 多个 class 导致竞态,推荐用
el.classList.toggle('fade-in', shouldShow)统一控制 - 如果元素初始不可见,记得在 HTML 中就加上
class="fade-out",否则首次添加fade-in时可能无过渡效果(缺少起始状态)
真正容易出问题的不是怎么写动画,而是忘记处理动画过程中的交互状态(比如淡出时用户还在输入)、没清理定时器或事件监听、或者在 SSR 渲染中直接用 JS 操作 DOM 导致水合失败。这些细节比动画本身更常引发线上问题。










