Transition动画为什么只在进入时生效,退出时不触发?

树行酱~ 阅读 42

我用CSS写了个简单的过渡效果,想让元素在显示和隐藏时都有淡入淡出动画,但目前只有显示的时候有动画,隐藏时直接消失了,完全没过渡。是不是哪里写错了?

我试过加了opacityvisibility,也确保了类名切换没问题,但退出动画就是不执行。

.fade-enter {
  opacity: 0;
  visibility: hidden;
}
.fade-enter-active {
  opacity: 1;
  visibility: visible;
  transition: opacity 0.3s ease, visibility 0.3s ease;
}
.fade-exit {
  opacity: 1;
  visibility: visible;
}
.fade-exit-active {
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.3s ease, visibility 0.3s ease;
}
我来解答 赞 5 收藏
二维码
手机扫码查看
2 条解答
 ___溪纯
兄弟,你这个代码看起来像是Vue的transition类名,但你是在手动切换类名对吧?

问题在于你切换类名的时机。元素从显示到隐藏时,你可能直接就把DOM移除了或者设置了display:none,这样过渡根本没时间执行。

正确的做法是:先添加exit类让元素进入退出状态,等过渡完成后再真正隐藏元素。

.fade-enter {
opacity: 0;
}
.fade-enter-to {
opacity: 1; transition: opacity 0.3s ease;
}
.fade-exit {
opacity: 1;
}
.fade-exit-to {
opacity: 0;
transition: opacity 0.3s ease;
}


如果你用Vue的话,直接用就行,框架会自动处理这些类名的添加和移除。

如果是原生JS手动控制,思路是这样的:

// 显示
element.classList.add('fade-enter', 'fade-enter-active');
// 强制触发重绘
element.offsetHeight;
element.classList.remove('fade-enter');

// 隐藏
element.classList.add('fade-exit', 'fade-exit-active');
// 等待过渡完成后再真正隐藏或移除
setTimeout(() => {
element.style.display = 'none';
element.classList.remove('fade-exit', 'fade-exit-active');
}, 300);


还有个常见坑就是visibility的过渡,有时候会导致问题,先只用opacity试试,确认是这个问题再加visibility。
点赞
2026-03-19 20:10
司空蒙蒙
问题出在 visibility: hidden 会立即生效,元素直接没了,transition 根本没机会跑。

退出动画需要用 transition-delay 让 visibility 延迟生效,等 opacity 动画跑完再隐藏:

.fade-exit-active {
opacity: 0;
visibility: hidden;
transition: opacity 0.3s ease, visibility 0s 0.3s;
}


或者更省事,直接用 pointer-events: none 代替 visibility,省得折腾延迟。
点赞 1
2026-02-28 20:02