如何用纯CSS实现弹跳动画?复用animate.css弹跳类未生效
纯CSS实现Toast弹跳动画(不引入全量animate.css)
之前尝试失效的核心原因
你现在的写法踩了两个非常容易绕进去的落地坑:
cssTransition的入参规则是只接收合法的CSS类名字符串,组件会在Toast进入/退出的生命周期节点,临时把这些类挂到Toast的DOM元素上触发样式。你之前直接把CSS样式规则当字符串塞到enter参数里,浏览器会把这段长文本当成类名去匹配选择器,根本找不到对应样式,自然不会触发动画。- 你之前复制animate.css源码的时候只抠了
.animate__animated的基础样式,漏了两个能让动画真正跑起来的关键部分:绑定到animate__bounceIn/animate__bounceOut上的关键帧定义、源码里全局定义的--animate-duration自定义CSS变量。 - 额外提醒:你之前尝试把带分号、冒号的CSS规则直接放到enter参数里的写法,哪怕单独把这段文本当类名去CSS里写选择器都不生效——因为这段字符串包含特殊符号,完全不符合CSS类名的合法命名规则,根本没法被正确匹配。
一步步落地的实现方案
步骤1:本地建独立CSS文件,只保留需要的动画片段
新建custom-toast-animate.css,把以下内容全部放进去,不需要引入任何第三方样式包:
/* 自定义动画时长变量 */ :root { --animate-duration: 1s; } /* 动画公共基础规则 */ .animate__animated { -webkit-animation-duration: calc(var(--animate-duration)); animation-duration: calc(var(--animate-duration)); -webkit-animation-fill-mode: both; animation-fill-mode: both; } /* 弹跳进入动画类 */ .animate__bounceIn { -webkit-animation-name: bounceIn; animation-name: bounceIn; } /* 弹跳退出动画类 */ .animate__bounceOut { -webkit-animation-name: bounceOut; animation-name: bounceOut; } /* 弹跳进入关键帧 */ @-webkit-keyframes bounceIn { 0% { opacity: 0; -webkit-transform: scale3d(.3, .3, .3); transform: scale3d(.3, .3, .3); } 50% { opacity: 1; -webkit-transform: scale3d(1.05, 1.05, 1.05); transform: scale3d(1.05, 1.05, 1.05); } 70% { -webkit-transform: scale3d(.9, .9, .9); transform: scale3d(.9, .9, .9); } 100% { -webkit-transform: scale3d(1, 1, 1); transform: scale3d(1, 1, 1); } } @keyframes bounceIn { 0% { opacity: 0; -webkit-transform: scale3d(.3, .3, .3); transform: scale3d(.3, .3, .3); } 50% { opacity: 1; -webkit-transform: scale3d(1.05, 1.05, 1.05); transform: scale3d(1.05, 1.05, 1.05); } 70% { -webkit-transform: scale3d(.9, .9, .9); transform: scale3d(.9, .9, .9); } 100% { -webkit-transform: scale3d(1, 1, 1); transform: scale3d(1, 1, 1); } } /* 弹跳退出关键帧 */ @-webkit-keyframes bounceOut { 0% { -webkit-transform: scale3d(1, 1, 1); transform: scale3d(1, 1, 1); } 20% { opacity: 1; -webkit-transform: scale3d(.9, .9, .9); transform: scale3d(.9, .9, .9); } 50%, 55% { opacity: 0; -webkit-transform: scale3d(.3, .3, .3); transform: scale3d(.3, .3, .3); } 100% { opacity: 0; -webkit-transform: scale3d(0, 0, 0); transform: scale3d(0, 0, 0); } } @keyframes bounceOut { 0% { -webkit-transform: scale3d(1, 1, 1); transform: scale3d(1, 1, 1); } 20% { opacity: 1; -webkit-transform: scale3d(.9, .9, .9); transform: scale3d(.9, .9, .9); } 50%, 55% { opacity: 0; -webkit-transform: scale3d(.3, .3, .3); transform: scale3d(.3, .3, .3); } 100% { opacity: 0; -webkit-transform: scale3d(0, 0, 0); transform: scale3d(0, 0, 0); } }
步骤2:替换项目里的全量包引入
原来代码里引全量animate.css的那行,换成引自己写的本地CSS文件即可,整体样式体积会比全量包减少90%以上:
import 'react-toastify/dist/ReactToastify.css' import './custom-toast-animate.css' // 替代全量animate.css引入
步骤3:修正cssTransition的配置
不需要把CSS代码塞进去,类名和你之前用全量包的时候保持一致就可以:
const bounce = cssTransition({ enter: 'animate__animated animate__bounceIn', exit: 'animate__animated animate__bounceOut', })
剩下的ToastContainer配置完全不用改,和你原来能正常跑的代码一模一样。
灵活调整提示
- 如果觉得
animate__前缀的类名麻烦,完全可以把所有类名改成自定义命名(比如改成toast-bounce-in),只要JSX里cssTransition传的类名和CSS文件里写的类名一一对应就行,不影响功能。 - 想调整动画时长的话,直接改
:root里的--animate-duration值即可,不需要动关键帧代码。
内容的提问来源于stack exchange,提问作者adeveloper
相关产品推荐
相关产品推荐

