纯CSS气泡动画需设容器position: relative或overflow: hidden,用transform: translateY()替代top/bottom避免重排,opacity与transform错峰控制,起始transform: translateY(100vh)+opacity: 0,10%–20%帧快速升至0.6–0.8,70%–90%帧缓降至0.2–0.3并scale(0.9),结尾translateY(-10vh),配合非整数animation-delay、椭圆border-radius、低alpha背景、≤20个气泡、移动端延长时长及pointer-events: none,才能实现自然流畅的“活”气泡效果。

直接用 @keyframes + transform: translateY() 就能实现,但关键不在“能不能动”,而在“动得自然、不卡、不溢出、不拖慢页面”——多数人卡在容器定位、动画参数和透明度节奏上。
气泡容器必须设 position: relative 或 overflow: hidden
否则气泡会飘出视口、触发滚动条,甚至在某些浏览器里完全不动。原因很简单:position: absolute 的气泡需要一个“参考系”,而默认的 static 父容器不提供这个参考系。
-
.bubble-container必须显式声明position: relative(推荐)或overflow: hidden - 如果用
body直接当容器,记得加margin: 0; padding: 0; height: 100vh;,否则气泡可能被截断 - 别用
top/bottom动画——它强制重排(reflow),translateY()走合成层,GPU 加速更稳
@keyframes 里 opacity 和 transform 要错峰控制
真实气泡不是“匀速上升+匀速淡入淡出”,而是先微显、中段饱满、快到顶时变薄变透。硬套 0%→100% 线性变化会显得假。
- 起始帧设
transform: translateY(100vh)(从屏幕最底端外入场)+opacity: 0 - 10%–20% 帧让
opacity快速升到 0.6~0.8,模拟气泡刚成型的清晰感 - 70%–90% 帧缓慢降
opacity到 0.2~0.3,同时scale(0.9)微缩,模拟远去/破裂前变形 - 结尾帧
transform: translateY(-10vh),不是 -100vh——留点余量,避免气泡“啪”一下消失
多个气泡要靠 animation-delay 和尺寸随机化破重复感
纯 CSS 实现“随机”,只能靠人工设不同 delay 和不同 width/height。JS 动态生成虽灵活,但纯 CSS 方案更轻量、无阻塞。
立即学习“前端免费学习笔记(深入)”;
- 每个
.bubble元素写死animation-delay: 0.5s、1.2s、2.7s这类非整数,比1s、2s更自然 - 用
border-radius: 50%+ 不同宽高(比如width: 12px; height: 18px;)做出椭圆气泡,比全圆更有水下真实感 - 背景色统一用
rgba(255,255,255,0.15)这类低 alpha,避免盖住底层内容;别用box-shadow模拟光晕——性能差且边缘糊 - 数量别超 20 个,太多会触发浏览器降帧;真要密集,加
will-change: transform仅对正在动画的元素动态加(用 JS 控制更准)
移动端适配要重设 vh 和动画时长
iOS Safari 对 100vh 解析不稳定(地址栏收放影响),且小屏设备动画太快会眩晕。不能直接复用桌面版数值。
- 把
translateY(-100vh)改成translateY(-120vh),确保所有机型都能完整飘出 - 动画总时长从桌面端的
4s提到6s,降低视觉压迫感 - 小尺寸气泡(
8px–16px)用animation-duration: 5s,大尺寸(30px+)用8s,模拟物理中气泡越大上升越慢 - 别忘了加
pointer-events: none到气泡元素上,否则会挡住下方按钮点击
真正难的不是让气泡动起来,是让它动得像“活的”——起速缓、中段稳、收尾轻,每一帧的 opacity、scale、timing-function 都得调。cubic-bezier(.22,.61,.36,1) 这类弹跳曲线比 ease-in-out 更有呼吸感,但只在关键路径上用,别全局套。


















