侧边栏回弹需用cubic-bezier(0.34,1.56,0.64,1)实现可控超调,叠加scaley形变与transform同曲线同步动画,并避免display:none、overflow:hidden等破坏渲染树的属性。

为什么直接用 transform: translateX() 没有回弹感
因为默认的 ease 或 ease-in-out 缓动函数只是平滑起止,不模拟物理惯性。浏览器不会自动“超调再回正”,必须显式用 cubic-bezier() 描述这种曲线。
常见错误是抄个高弹性值(比如 cubic-bezier(0.175, 0.885, 0.32, 1.275))直接套用——它在菜单位移场景下容易过冲太多,导致视觉晃动、内容短暂错位。
- 推荐起点值:
cubic-bezier(0.34, 1.56, 0.64, 1)—— y1 > 1 实现可控超调,y2 = 1 确保终点精准停住 - 别写死在
.sidebar.open里,必须定义在基础类(如.sidebar)中,否则首次展开无动画 - 过渡属性只写
transform,避免all引入无关重绘
如何让侧边栏真正“弹”起来而不是滑过去
纯位移不够,得叠加形变。阻尼感来自两层同步动画:水平位移 + 垂直压缩/拉伸。
关键不是加多复杂,而是两个动画用同一贝塞尔函数、同一时长、同一触发时机:
- 位移:
transform: translateX(0) scaleY(1) - 初始态:
transform: translateX(-100%) scaleY(0.98)(轻微预压,增强释放感) - 过渡声明:
transition: transform 0.35s cubic-bezier(0.34, 1.56, 0.64, 1) - 必须设
transform-origin: left center,否则scaleY会以中心缩放,造成左右不对称抖动
移动端拖拽后回弹失效或卡顿的根源
iOS Safari 和部分安卓 WebView 对 touch 事件默认启用 passive: true,一旦你调 preventDefault()(比如阻止页面滚动),动画帧可能被静默丢弃。
同时,浏览器无法对未启用硬件加速的元素做高效合成动画:
- 绑定
touchstart时必须传{ passive: false } - 拖拽中动态加
style="will-change: transform",松手后立刻移除 - 别和
transform: translateZ(0)叠加使用——现代浏览器已自动启用 GPU 加速,冗余声明反而触发重绘 - 位移计算用
getBoundingClientRect().left做基准,不用clientX差值(缩放、快速滑动下误差大)
overflow: hidden 和 display: none 是阻尼动画的隐形杀手
这两个属性会让元素脱离渲染树或强制重排,transform 和 transition 全部失效。尤其 display: none 是最常被忽略的“断点”。
正确做法是让侧边栏始终在文档流中参与布局和事件:
- 初始隐藏用
transform: translateX(-100%)+visibility: hidden+opacity: 0 - 展开时统一改
visibility: visible、opacity: 1、transform: translateX(0) scaleY(1) - 父容器禁用
overflow: hidden—— 它会裁切scaleY的形变区域,看起来像“突然弹出” - 遮罩层(
.overlay)必须设pointer-events: auto,且z-index高于侧边栏,否则拖拽时事件捕获异常
display、漏了 will-change、或贝塞尔函数没写在基础类里,都会导致“第一次没动画”或“收起时硬切”。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











