toast 应使用 position: fixed + top/left 定位与 transform/opacity 动画实现,配合 settimeout 控制显隐生命周期;需设 z-index、keyframes 滑入动画、visibility 过渡回收,并注意移动端 fixed 抖动及多 toast 队列管理。

直接用 transform + opacity 动画 + setTimeout 控制生命周期,不依赖框架也能稳定实现;关键在动画时序和脱离文档流的定位方式。
Toast 容器必须用 position: fixed 脱离文档流
如果用 position: absolute 或默认 static,弹窗会随页面滚动偏移、被其他元素遮挡,或触发意外重排。顶部固定位置需明确设置 top 和 left:
-
top: 16px(避免紧贴浏览器顶边,留出安全间距) -
left: 50%+transform: translateX(-50%)实现水平居中(比margin-left: -width/2更可靠) - 务必加
z-index: 1000,否则可能被header、modal等覆盖
滑入动画要用 @keyframes 配合 transform: translateY()
CSS 动画性能优于 top 或 margin-top,且能与 opacity 同步过渡。定义两个关键帧即可:
@keyframes toast-in {
from {
opacity: 0;
transform: translateY(-20px) translateX(-50%);
}
to {
opacity: 1;
transform: translateY(0) translateX(-50%);
}
}
- 动画名必须唯一,避免和其他组件冲突(比如别叫
in) - 起始位移
-20px比-100%更可控——后者在不同容器高度下表现不一致 - 动画时长建议
0.3s,太快用户来不及识别,太慢影响反馈节奏
自动消失靠 JS 控制 visibility + transition 回收
不能只靠 display: none,否则动画无法反向播放。正确做法是:动画结束后加一个「隐藏态」类,用 visibility: hidden + opacity: 0 触发退出动画:
- 显示时添加
toast--show类,激活toast-in动画 - 300ms 后调用
setTimeout添加toast--hide类,该类定义opacity: 0和transform: translateY(-20px) -
toast--hide必须带transition: opacity 0.2s, transform 0.2s,否则退出无动画 - 动画结束后再用
addEventListener('transitionend')移除整个 DOM 节点,避免残留
移动端要注意 pointer-events 和 scroll-behavior 冲突
某些 iOS Safari 下,fixed 元素在页面滚动时会“抖动”或延迟渲染,尤其配合 overflow: hidden 的父容器时:
- 给
body加touch-action: manipulation可缓解 - Toast 元素自身设
pointer-events: none,防止遮挡下方点击(除非你真需要 Toast 可点击) - 若页面用了
scroll-behavior: smooth,Toast 出现瞬间可能触发滚动跳变,临时禁用它更稳妥
真正难处理的是多 Toast 叠加时的队列管理——CSS 动画本身不支持暂停/排队,得靠 JS 维护状态栈,这点容易被忽略。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











