Use FLIP for Layout-Like Motion
SHOULD: When a layout change genuinely must animate (list reorder, card expanding into a detail view), use FLIP — First, Last, Invert, Play: read the start rect, apply the final layout, read the end rect, apply the inverse `transform`, then release it in one rAF and let the compositor interpolate back to zero. Layout runs twice instead of 60x/sec. Measure ONCE and batch all DOM reads before writes — a `getBoundingClientRect()` inside the loop forces a synchronous layout every tick. (Does not contradict `layout-flex-over-measurement`: that bans JS measurement to BUILD a static layout; FLIP is the sanctioned way to ANIMATE a layout change.)
When a layout change genuinely must animate, measure once and play it back as a transform instead of animating geometry
Bad
Good
Why it matters
Sometimes the thing that changes really is layout: a list reorders, a card expands into a detail view. FLIP — First, Last, Invert, Play — lets you animate that without ever animating a layout property. Read the start rect, apply the final layout in one go, read the end rect, apply the inverse transform so the element still *looks* like it is at the start, then release it in a single rAF and let the compositor interpolate the transform back to zero.
The result is pixel-identical to animating `top`/`left`/`width`, but the browser does layout exactly twice instead of sixty times a second. The two supporting rules are the ones people break: "measure once, then animate via transform or opacity" and "batch all DOM reads before writes" — a `getBoundingClientRect()` inside the animation loop forces a synchronous layout on every tick, which is layout thrashing with extra steps.
Note this does not contradict layout-flex-over-measurement: that rule says do not use JS measurement to *build* a static layout. FLIP is the sanctioned technique for the case where a layout change must be *animated*.