toast进入动画必须重写@keyframes toast-show并加!important,因bootstrap通过animation属性强制播放而非transition;直接改.transform或opacity无效,且需确保无data-bs-animation="false"干扰。

Toast 的进入动画不能靠修改 .toast 默认样式直接生效,必须覆盖 .toast.show 触发的 @keyframes 和过渡属性。
为什么直接改 transform 或 opacity 没用?
Bootstrap 5 的 toast 进入动画由两部分驱动:一是 .toast.show 类添加的 animation 声明(调用内置 toast-show 动画),二是 CSS 变量 --bs-toast-zindex 和 --bs-toast-padding-x 控制布局。单纯给 .toast 加 transition 或改 transform 不会触发,因为动画是通过 animation 属性强制播放的。
常见错误现象:.toast { transform: translateY(-20px); opacity: 0; transition: all 0.3s; } —— 完全无效,页面加载后 toast 仍按默认方式“弹”出来。
- Bootstrap 5.3+ 使用
@keyframes toast-show定义了从opacity: 0; transform: translateX(100%)到opacity: 1; transform: translateX(0)的动画 - 该动画被绑定在
.toast.show上,且带!important(见源码),所以必须重写整个@keyframes并确保优先级足够 - 动画时长、缓动函数、起始位移都由这个 keyframes 决定,不是靠 class 切换过渡
覆盖 @keyframes toast-show 的正确写法
在你的自定义 CSS 文件中(必须在 Bootstrap CSS 之后加载),重写 @keyframes toast-show,并确保新动画名与原名一致:
@keyframes toast-show {
from {
opacity: 0;
transform: translateY(20px) scale(0.95);
}
to {
opacity: 1;
transform: translateY(0) scale(1);
}
}
注意:transform 必须包含所有要动画的属性(如同时改 scale 和 translateY),否则未声明的属性会回退到初始值(比如只写 translateY,scale 就会跳变)。
- 动画时长由
.toast.show的animation-duration控制,默认是0.3s,可一并覆盖:.toast.show { animation-duration: 0.4s !important; } - 缓动函数默认是
cubic-bezier(0.25, 0.46, 0.45, 0.94),如需更柔和,加animation-timing-function: ease-out !important; - 不要漏掉
!important—— Bootstrap 源码里用了!important,不加就可能被覆盖失败
避免和 data-bs-animation="false" 冲突
如果 toast 初始化时加了 data-bs-animation="false"(例如手动控制显示逻辑),那它根本不会触发动画,此时覆盖 @keyframes 也无效。
- 检查 HTML 中是否误加了该属性:
<div class="toast" data-bs-animation="false"> <li>若需保留 JS 控制但又要动画,去掉该属性,改用 <code>show()方法(它会自动加.show类并触发动画) - 若 toast 是动态插入 DOM 后再
show(),确保插入后、调用前已存在.toast结构,否则show()可能因找不到元素而静默失败
真正起作用的是 @keyframes + .toast.show 的组合,而不是某个 class 的过渡;很多人卡在没删掉 data-bs-animation="false" 或忘了加 !important,结果调了半小时发现动画压根没跑。











