You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 09:55:11