红包雨需用CSS @keyframes定义下落动画并配合JS动态创建/销毁.red-envelope元素,禁用transition,注意Safari兼容性及内存泄漏防护。

用 CSS 动画 + JavaScript 控制红包元素生成
Bootstrap 本身不提供“红包雨”这类动画能力,它只是 UI 框架,真正实现下落效果靠的是原生 CSS @keyframes 和 JS 动态插入 DOM。别试图找 bootstrap.js 里的红包组件——它根本不存在。
核心思路是:用 JS 创建一堆 ,定位在视口顶部随机横坐标,再通过 CSS 设定从上到下、带旋转/缩放的下落动画,结束后自动移除节点。
- 红包容器建议设为
position: fixed; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none;,避免遮挡页面交互 - 每个红包元素必须设
position: absolute,且初始top: -100px(确保从视口外进入) - 动画时长建议控制在
2.5s ~ 4s之间,太短显得突兀,太长影响密集感 - 别用
transition替代@keyframes—— transition 无法实现“随机起点 + 多属性同步变化”的红包飘落感
红包样式用 Bootstrap 工具类快速搭形,但动画必须手写
可以利用 Bootstrap 的 bg-danger、rounded-circle、shadow-sm 快速做出红包基础形态,但所有运动逻辑(位移、旋转、透明度衰减)必须靠自定义 CSS 实现。
例如:
.red-envelope {
width: 40px;
height: 40px;
background-color: #e74c3c;
border-radius: 50%;
position: absolute;
animation: fall linear forwards;
}
@keyframes fall {
0% {
transform: translateY(-100px) rotate(0deg) scale(0.8);
opacity: 1;
}
100% {
transform: translateY(calc(100vh + 100px)) rotate(720deg) scale(1.2);
opacity: 0;
}
}
- 注意
calc(100vh + 100px)是为了确保动画结束时红包彻底离开视口底部,避免残留白边 -
rotate(720deg)比360deg更显轻盈,视觉上更像被气流带偏 - 别给
.red-envelope加transition,会和animation冲突,导致首帧卡顿
JS 控制生成节奏和数量,避免内存泄漏
高频创建 DOM 节点容易撑爆内存,尤其在长时间运行的红包雨中。关键不是“多快”,而是“可控+可停”。
- 用
setInterval启动生成,但必须存引用以便后续clearInterval,比如:let rainTimer = setInterval(...) - 每次生成前检查当前页面中
.red-envelope元素数量,超过 150 个就return,防止堆积 - 动画结束时务必监听
animationend事件并调用remove(),否则节点永远留在 DOM 树里 - 移动端需加判断:
if ('ontouchstart' in window),避免在手机上误触触发多次生成
兼容性坑:Safari 对 animation-fill-mode 和 transform 的处理最棘手
Safari(尤其是 iOS 15 及更早)对 animation-fill-mode: forwards 支持不稳定,常导致红包掉到一半就突然消失或卡住。这不是 Bootstrap 的问题,是 WebKit 渲染引擎的老毛病。
- 绕过方式:不用
forwards,改用 JS 在animationend中显式设置最终样式,再移除元素 - transform 缩放值如果写成
scale(1.2),Safari 可能渲染模糊,建议补全为scale3d(1.2, 1.2, 1) - 别依赖
prefers-reduced-motion媒体查询自动禁用动画——很多安卓微信 WebView 根本不识别这个特性 - 测试时一定要真机连 Safari 开发者工具调试,模拟器经常骗人
红包雨真正的复杂点不在“怎么动”,而在于“什么时候不该动”:用户切走标签页时暂停、滚动页面时降频、动画卡顿时自动回收节点——这些细节没处理好,再炫的效果也撑不过 10 秒。











