纯CSS下雨效果需用@keyframes配合transform实现斜向匀速下落,通过随机xy位移、负延迟错峰、分层渲染及Safari兼容优化确保真实感与性能。

用 @keyframes 控制雨滴下落路径和速度
纯 CSS 实现下雨效果,核心是让大量“雨滴”元素沿斜线匀速下落并循环。不能只靠 translateY 垂直掉,真实雨丝是倾斜的(通常 20°–30°),得用 translate 同时控制 X 和 Y 方向位移。
实操建议:
- 定义
@keyframes rain-fall,起始位置设在视口上方随机高度、偏左或偏右,终点落在视口下方(transform: translate(20px, 100vh)这类) - 动画时长控制在 0.5s–1.2s 之间:太慢像雾,太快像雪粒;不同长度可制造远近雨层
- 加
ease-in缓动——雨滴初速慢、中段快,比线性更自然 - 避免用
top/left动画:重排开销大,transform才走合成层
生成雨滴要用伪元素还是真实 DOM 节点?
伪元素(::before/::after)更轻量,但单个容器最多两个;真实 <div class="raindrop"> 更可控,适合做分层雨(前/中/后景)。
常见错误现象:z-index 错乱导致雨滴被内容盖住,或所有雨滴堆在左上角不动。
立即学习“前端免费学习笔记(深入)”;
实操建议:
- 给雨容器设
position: fixed; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none; - 每个雨滴元素设
position: absolute;,用 JS 或 CSS 自定义属性(--x,--y)注入初始坐标 - 若用伪元素,必须确保父容器有
position: relative且不被裁剪(overflow: visible) - 别忘了
will-change: transform提示浏览器优化渲染(尤其 Safari)
animation-delay 随机化是关键,但别用 JS 算
每滴雨的延迟值必须错开,否则整屏雨滴会同步闪现、同步消失,一眼假。但用 JS 循环设 style.animationDelay 在大量雨滴时卡顿明显。
实操建议:
- 用 CSS 自定义属性批量生成:比如
--delay: calc(var(--i) * 0.1s),配合:nth-child(n)或 CSS Houdini(较新) - 更稳的方案:预设 5–8 组 delay 类,如
.delay-1 { animation-delay: -0.3s; },用 JS 随机分配 class - 避免 delay 值集中在某一小段区间(比如全在 -0.1s ~ -0.2s),会导致局部密集、其余空白
- 注意:负 delay 是合法的,表示动画从中间某一帧开始播放,不是 bug
移动端和 Safari 的兼容性坑
Safari 对 transform + opacity 同时动画支持不稳定,常出现雨滴闪烁或突然消失;iOS 滚动时还可能触发 will-change 泄漏导致内存上涨。
实操建议:
- 不用
opacity做淡入淡出,改用scaleY(0)→scaleY(1)模拟雨丝“凝结”效果,更省 - 对 iOS 加
@supports (-webkit-appearance: none)单独降级:减少雨滴数量、关掉 blur 滤镜 - 禁用
pointer-events: none时务必测试微信内嵌浏览器——某些版本会误判为可点击区域 - 别依赖
prefers-reduced-motion自动关动画:很多用户没开,但电量低时系统会强制限制,得监听reduceMotion变化手动停
最麻烦的其实是雨滴密度和设备像素比的匹配:高 DPR 屏幕下,1px 宽的雨丝实际占 2–3 物理像素,得用 transform: scale(0.5) 补偿,否则看起来像毛毛雨。










