推荐用 opacity 和 transform 配合 transition 实现平滑入场/出场动画,通过 class 切换控制状态,监听 transitionend 事件确保动画完成后再卸载元素,并注意兼容性与性能优化。

用 transition 控制入场/出场的显隐切换
直接用 display: none 或 visibility: hidden 无法触发动画,因为它们不参与 CSS 过渡计算。真正能平滑过渡的是 opacity 和 transform 这类可动画属性。
推荐做法:用 opacity 控制淡入淡出,配合 transform: scale() 或 translateY() 做位移/缩放,再用 transition 统一声明变化属性和时长。
-
opacity从 0 → 1(入场),1 → 0(出场) -
transform可设为translateY(20px)→translateY(0)实现上滑入场 - 务必给元素设置初始
transition: opacity 0.3s ease, transform 0.3s ease - 切记:
transition要写在「常态」样式里(即非:hover或.active等触发态),否则出场时会失效
用 class 切换控制动画状态而非内联样式
用 JavaScript 直接操作 style.opacity 或 style.transform 会覆盖 transition,导致动画跳变。正确方式是通过增删 class 控制状态。
例如定义两个 class:
.fade-enter {
opacity: 0;
transform: translateY(10px);
}
.fade-enter-active {
opacity: 1;
transform: translateY(0);
transition: opacity 0.25s ease, transform 0.25s ease;
}
JS 中只需:el.classList.add('fade-enter') → el.classList.add('fade-enter-active')(注意先后顺序),或用 el.classList.toggle('show') 配合 CSS 的 .show 规则。
- 入场:先加基础隐藏类(如
fade-enter),再加激活类(fade-enter-active) - 出场:先移除激活类,再用
setTimeout移除隐藏类(否则 DOM 立即消失,动画中断) - 避免用
el.style.opacity = '0'—— 它会覆盖 CSS 中的transition
处理 display: none 导致的动画中断问题
组件隐藏后常需彻底卸载(比如 Vue 的 v-if、React 的条件渲染),但直接设 display: none 会让动画来不及播完就销毁。必须等动画结束再移除元素。
- 监听
transitionend事件,确认propertyName是opacity或transform再执行清理 - 用
getComputedStyle(el).opacity === '0'辅助判断是否真已隐藏,避免事件误触发 - 若使用
requestAnimationFrame+offsetHeight强制重排,可解决 Safari 中首次动画不触发的问题 - 不要依赖
setTimeout固定延时 —— 用户系统性能不同,动画实际耗时可能偏差
兼容性与性能关键点
老版本 Safari 对 transform + opacity 同时过渡支持不稳定;Chrome/Firefox 没问题。移动端还要防卡顿。
- 强制开启硬件加速:给动画元素加
transform: translateZ(0)或will-change: opacity, transform - 避免对
height、width、top/left做过渡 —— 它们触发 Layout,开销大 - IE11 不支持
transitionend的propertyName字段,需用event.propertyName兜底 - 如果组件内含大量子元素,动画期间避免 JS 频繁修改 DOM,否则帧率骤降
最易被忽略的是:动画类名切换和 transition 声明的时机必须严格匹配,差一行 CSS 或一次 class 操作顺序错,就会“闪一下”或完全不动。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











