纯css橡皮筋动画本质是用@keyframes配合scale3d()非线性缩放模拟弹性形变,无需js触发,但仅为视觉反馈;关键帧需设多段过冲与微调(如0%/35%/45%/60%/75%/100%),配cubic-bezier强化弹性,移动端应避免依赖:hover。

纯 CSS 实现的“橡皮筋动画”本质是用 @keyframes 配合非线性缩放(尤其是 scale3d() 或拆分 scaleX()/scaleY())模拟弹性形变,**不需要 JS 就能触发**,但要注意:它只是视觉反馈,不是物理引擎,也不带惯性或阻尼计算。
为什么用 scale3d() 而不是 scale()
因为 scale3d(1.25, 0.75, 1) 能独立控制 X/Y/Z 三个轴的缩放,让元素在横向拉伸时纵向压缩,再反向回弹,更贴近真实橡皮筋的“体积守恒感”。而 scale(1.25) 是等比缩放,看起来像整体放大,缺乏扭曲张力。
-
scale3d(x, y, z)中 z 参数通常固定为1(2D 场景下不影响) - 浏览器对
scale3d()的硬件加速支持比scale()更稳定,尤其在移动端 - 若需兼容极老 Android(≤4.3),可降级为
transform: scaleX(1.25) scaleY(0.75),效果接近
@keyframes rubberBand 的关键帧怎么设才不僵硬
生硬的橡皮筋动画往往卡在“起始→最大→结束”三段。真正有弹性的节奏需要:先快冲、再过冲、多次微调、最后缓停。参考下面这个被验证有效的比例:
0% { transform: scale3d(1, 1, 1); }
35% { transform: scale3d(1.25, 0.75, 1); } /* 快速拉伸+压扁 */
45% { transform: scale3d(0.75, 1, 1); } /* 反向过冲(横向收缩) */
60% { transform: scale3d(1.2, 0.8, 1); } /* 回调,但未完全复位 */
75% { transform: scale3d(1.05, 0.95, 1); } /* 微调,逼近原状 */
100% { transform: scale3d(1, 1, 1); }
- 时间点不用死守 35%/45%,可微调 ±5% 来匹配你的动画时长(比如
1.2s时把 35% 改成 30%) - 避免在 100% 前就回到
scale3d(1,1,1),否则最后一帧会“啪”一下收住,失去余韵 - 如果用于按钮,建议加
animation-timing-function: cubic-bezier(.68,-.55,.27,1.55)强化弹性感
hover 触发 vs click 触发:别忽略 pointer-events 和移动端兼容
直接写 .btn:hover { animation: rubberBand 1s; } 在桌面端没问题,但在 iOS/Android 上,:hover 不可靠——轻触可能不触发,或延迟触发,甚至误触发。
- 移动端优先用 JS 绑定
touchstart+classList.add('is-rubber'),再用 CSS 动画监听该 class - 若坚持纯 CSS,至少补一句:
.btn { pointer-events: auto; }(某些场景下父容器可能禁用了 pointer-events) - 避免对
<input type="button">直接写 hover 动画——部分 Android WebView 对表单控件的伪类支持异常
真正难的不是写出这段动画,而是判断它该不该出现:频繁缩放会影响可访问性(尤其对前庭敏感用户),也容易干扰屏幕阅读器焦点流。用之前,先问自己——这个弹性反馈是否提供了明确的状态信息?还是仅仅为了“酷”?
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











