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

如何在React中使用keyframes实现模态框关闭时的下滑动画

解决方案

1. 修正CSS代码

你当前的下滑关键帧逻辑写反了,0%对应动画起始状态,100%对应结束状态,同时要补充动画结束后保持最终状态的配置,还要把公共样式抽到基础.modal类,避免切换类时样式丢失:

/* 基础模态框样式,公共属性统一抽离 */
.modal {
    margin: auto;
    top: 10%;
    position: fixed;
    z-index: 999;
    height: 100%;
}
.toDisplayModal{
    animation: slideup 0.3s ease forwards;
}
.toCloseModal {
    animation: slidedown 0.3s ease forwards;
}

@keyframes slideup {
    0% {
        transform: translateY(400px);
        animation-timing-function: ease-out;
    }
    60% {
        transform: translateY(20px);
        animation-timing-function: ease-in;
    }
    80% {
        transform: translateY(10px);
        animation-timing-function: ease-out;
    }
    100% {
        transform: translateY(0px);
    }
}
@keyframes slidedown {
    /* 动画起始:模态框正常展示的位置 */
    0% {
        transform: translateY(0px);
        animation-timing-function: ease-out;
    }
    20% {
        transform: translateY(10px);
        animation-timing-function: ease-in;
    }
    40% {
        transform: translateY(20px);
        animation-timing-function: ease-out;
    }
    /* 动画结束:完全滑出可视区域 */
    100% {
        transform: translateY(400px);
    }
}

animation-fill-mode: forwards的作用是让动画播放完成后保持最后一帧的状态,避免动画结束后回弹到初始位置。

2. 修正React状态逻辑

核心问题是不能点击关闭后直接隐藏/卸载模态框,要等下滑动画播放完成后再执行隐藏操作,逻辑参考如下:

import { useState } from 'react'
import classnames from 'classnames'

// 组件内部逻辑
const [showModal, setShowModal] = useState(false)
const [closeModal, setCloseModal] = useState(false)

// 关闭按钮触发方法
const handleClose = () => {
  // 先添加关闭动画类触发下滑效果
  setCloseModal(true)
  // 等待动画播放完成(时长和CSS中配置的0.3s保持一致)
  setTimeout(() => {
    setShowModal(false)
    // 重置关闭状态,方便下次打开模态框时正常触发上滑动画
    setCloseModal(false)
  }, 300)
}

// 渲染逻辑
return (
  <>
    <button onClick={() => setShowModal(true)}>打开模态框</button>
    {showModal && (
      <div
        className={classnames(styles.modal, {
          [styles.toDisplayModal]: showModal && !closeModal,
          [styles.toCloseModal]: closeModal,
        })}
      >
        <div className={styles.container}>
          <CloseButton onClick={handleClose} />
          <div> text </div>
        </div>
      </div>
    )}
  </>
)

内容的提问来源于stack exchange,提问作者RandomDeveloper

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 18:45:05