flip动画的核心是javascript控制的四步状态管理:first→last→invert→play,通过transform和opacity反向插值实现高性能过渡,避免width/height等触发重排的属性。

FLIP动画的核心不是CSS,是JavaScript控制的四步状态管理
FLIP不是某个CSS属性或HTML标签,而是用JavaScript精准捕获元素“前”(First)和“后”(Last)布局状态,再用transform和opacity反向插值实现高性能过渡的模式。浏览器原生不支持自动FLIP,必须手动实现四步:**F**irst → **L**ast → **I**nvert → **P**lay。
常见错误是直接对width/height/top/left做CSS transition——这会触发重排,卡顿明显,尤其在列表增删、网格重排等场景下几乎不可用。
- 只对
transform和opacity做transition,确保合成层渲染 - 用
getBoundingClientRect()捕获First和Last位置,别用offsetTop等可能受父级影响的属性 - Invert阶段要立刻应用逆向
transform(比如Last位置减去First位置),且必须在下一帧前完成(用requestAnimationFrame包裹)
如何用requestAnimationFrame安全执行Invert阶段
Invert不是“加个class就完事”,它要求在浏览器绘制上一帧后、计算下一帧前,把元素“视觉上挪回原位”,靠的是立即生效的内联transform。如果写成element.style.transform = 'translate(...)'后直接element.classList.add('animate'),很可能因样式计算时机问题导致跳变。
正确做法是把Invert和Play拆进两个连续的requestAnimationFrame回调:
const first = el.getBoundingClientRect();
el.classList.add('moving');
// 强制重排,拿到Last位置
const last = el.getBoundingClientRect();
// Invert:立刻反向位移
el.style.transform = `translate(${first.left - last.left}px, ${first.top - last.top}px)`;
// Play:下一帧清除Invert,让transition生效
requestAnimationFrame(() => {
el.style.transform = '';
el.classList.add('animate');
});
漏掉requestAnimationFrame嵌套,或把Invert写在Play之后,动画就会闪一下或完全不启动。
React中用useLayoutEffect实现FLIP,避免useEffect的时机错位
在React里用useEffect读取getBoundingClientRect()大概率拿到旧尺寸——因为DOM更新发生在commit阶段,而useEffect在paint之后才执行。必须用useLayoutEffect,它在DOM变更后、浏览器paint前同步运行,能保证读到最新布局。
- First状态在
useLayoutEffect首次挂载时记录 - Last状态在数据变化后、DOM重排完成瞬间再次调用
useLayoutEffect获取 - 用
ref缓存节点,避免重复查询 - 不要在
useLayoutEffect里直接setState,否则会触发同步重渲染,破坏FLIP节奏
一个典型坑是:在useLayoutEffect里修改了state,又依赖这个state触发下一次useLayoutEffect,形成死循环+布局抖动。
Grid和Flex容器内FLIP的特殊处理:避免隐式重排干扰
当目标元素在display: grid或flex容器中,其位置不仅由自身决定,还受兄弟元素影响。单纯对单个元素做FLIP,兄弟项可能在动画过程中“抽搐”——因为它们的布局也在实时变化。
解决方法不是给所有兄弟加FLIP,而是冻结整个容器的布局流:
- 在First阶段,对容器设置
position: absolute或pointer-events: none(视需求而定),防止交互干扰 - 用
getComputedStyle(container).getPropertyValue('grid-template-rows')等捕获容器原始定义,必要时暂存 - 动画期间,把目标元素用
position: absolute脱离文档流,再对其做FLIP;结束后恢复 - 注意:
grid-area或order变化无法仅靠transform模拟,必须配合容器重排 + FLIP组合策略
没意识到容器级布局依赖,只盯着单个元素做FLIP,最后效果就是“主元素动了,周围全乱了”。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











