如何实现CSS动画反向效果?解决元素显示→隐藏无过渡问题
简洁实现滑入滑出双向动画方案
问题根源是display: none会让元素瞬间脱离文档流,反向动画根本没机会执行。这里给你两个简洁的方案,不用复杂的hack:
方案一:用CSS Transition替代关键帧(最简洁)
放弃display切换,改用transform和opacity结合过渡,既能实现滑入滑出,又不需要额外JS:
.slide-panel { position: absolute; /* 默认处于屏幕外 */ transform: translateX(-100%); opacity: 0; /* 过渡动画 */ transition: transform 1s ease, opacity 1s ease; } .slide-panel.open { /* 显示时回到原位 */ transform: translateX(0); opacity: 1; }
<div className={`slide-panel ${open ? 'open' : ''}`}> This slides open and closes smoothly when state changes. </div>
方案二:基于你的关键帧动画实现反向效果
如果你坚持用关键帧动画,可以定义反向的slide-out动画,配合少量JS监听动画结束事件,完成后再设置display: none:
@keyframes slide-in { 0% { left: -100vw; } 100% { left: 0; } } @keyframes slide-out { 0% { left: 0; } 100% { left: -100vw; } } .slide-in { animation: slide-in 1s forwards; } .slide-out { animation: slide-out 1s forwards; } .hidden { display: none; }
import { useEffect, useRef } from 'react'; // 组件内部分 const divRef = useRef(null); useEffect(() => { const div = divRef.current; if (!div) return; const handleEnd = () => { if (!open) div.classList.add('hidden'); }; div.addEventListener('animationend', handleEnd); if (open) { div.classList.remove('hidden', 'slide-out'); div.classList.add('slide-in'); } else { div.classList.remove('slide-in'); div.classList.add('slide-out'); } return () => div.removeEventListener('animationend', handleEnd); }, [open]); // JSX部分 <div ref={divRef} className="hidden" style={{ position: 'absolute' }}> This slides open and closes with keyframe animations. </div>
两种方案都避开了你提到的复杂hack,方案一甚至不需要JS监听,是最简洁的实现方式。
内容的提问来源于stack exchange,提问作者Zack
相关产品推荐
相关产品推荐

