应先设置 overscroll-behavior: contain(滚动容器)、none(html/body)禁用全局回弹;再用 transform: scaley() + will-change 实现弹性形变;最后用 spring() 缓动完成回弹动画。

用 overscroll-behavior 阻止默认下拉回弹干扰
原生 iOS 的 Rubber Band 效果只在 WebView 或原生滚动容器中触发,但网页里一旦启用 body 滚动,下拉到顶时会触发整个页面的 overscroll 回弹,和你想要的「局部果冻弹动」冲突。关键第一步不是加动画,而是关掉它:
- 给滚动容器(比如
.scroll-container)设overscroll-behavior: contain,防止滚动穿透到html/body - 务必同时给
html和body加overscroll-behavior: none,否则 Safari 仍可能触发全局回弹 - 这个属性在 Safari 16.4+ 和 Chrome 63+ 支持良好,但旧版 iOS Safari 不支持——这时得靠 JS 拦截
touchmove阻止默认行为
用 transform: scaleY() + will-change 实现弹性形变
纯 CSS 实现「果冻感」的核心是让容器在拖拽过程中动态缩放 Y 轴,并带非线性缓动。不能用 height 动画(触发布局重排),必须用合成层属性:
- 给目标容器设
transform-origin: top center,保证缩放从顶部锚定 - 拖拽时动态设置
transform: scaleY(1.2)这类值,数值按拖拽距离比例控制(例如:拖 100px →scaleY(1.3),上限建议封顶在1.5防止过度变形) - 加
will-change: transform提前升层,避免 Safari 下卡顿;但别滥用——仅在拖拽开始时添加,结束时移除 - 注意:
scaleY会影响子元素文字渲染,若内容有文字,建议包裹一层div并对内层反向缩放(scaleY(0.8))做视觉补偿
用 spring() 缓动函数模拟物理回弹
CSS 的 spring(mass, stiffness, damping, velocity) 是 Safari 原生支持的物理缓动函数,比 cubic-bezier 更贴近 iOS 弹性效果:
- 典型参数组合:
spring(1, 100, 10, 0)—— mass 小、stiffness 中等、damping 低,能产生明显振荡后收敛 - 只用于「释放后的回弹动画」,不要用在拖拽过程中(拖拽是即时响应,不该有缓动)
- 必须配合
transition: transform 0.5s使用,且transition要写在容器上,而非伪类或 JS 内联样式(否则 Safari 可能不触发) - Android Chrome 不支持
spring(),需降级为cubic-bezier(0.22, 0.61, 0.36, 1)(iOS 系统级回弹近似曲线)
监听 touchmove 计算拖拽偏移量(必要时)
当 overscroll-behavior 不可用(如 iOS 15.6 以下),或需要更精细控制形变逻辑时,JS 是绕不开的:
- 监听容器的
touchstart→ 记录startY;touchmove→ 计算deltaY = currentY - startY,但仅当scrollTop === 0 && deltaY > 0时才更新transform - 关键点:必须调用
event.preventDefault(),且容器需有touch-action: none,否则 Safari 会抢走事件 - 松手后用
element.animate()触发spring()回弹,避免直接改style.transform导致过渡失效 - 别忘了处理
mouse事件兼容(桌面调试用),但生产环境可忽略,因为 Rubber Band 是移动端专属交互
实际最易被忽略的是 transform-origin 的锚点位置和 overscroll-behavior 的层级覆盖关系——少设一个,整个弹性就变成页面晃动或者完全没反应。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











