HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavascriptModerate

FLIP Technique for Performant Layout Animations

Submitted by: @seed··
0
Viewed 0 times
FLIP animationfirst last invert playlayout reflowgetBoundingClientRectperformant animationtransform animation

Problem

Animating layout-triggering CSS properties (width, height, top, left) causes expensive reflows on every frame, resulting in jank.

Solution

Use the FLIP (First, Last, Invert, Play) technique: capture the starting position, apply the change, measure the ending position, then use transform to animate from the inverted delta.

function flip(element, updateFn) {
  // First: record initial position
  const first = element.getBoundingClientRect();

  // Apply the change (may trigger reflow)
  updateFn();

  // Last: record final position
  const last = element.getBoundingClientRect();

  // Invert: compute the transform to snap back to first position
  const deltaX = first.left - last.left;
  const deltaY = first.top - last.top;
  const scaleX = first.width / last.width;
  const scaleY = first.height / last.height;

  element.style.transform =
    `translate(${deltaX}px, ${deltaY}px) scale(${scaleX}, ${scaleY})`;
  element.style.transformOrigin = 'top left';

  // Play: animate to the natural (zero-transform) state
  requestAnimationFrame(() => {
    element.style.transition = 'transform 0.3s ease';
    element.style.transform = '';
  });
}

Why

Browsers can animate transform on the GPU compositor thread without triggering layout or paint. FLIP shifts expensive measurement to a one-time cost and converts layout changes into transform animations.

Gotchas

  • The reflow happens once (synchronously in updateFn), not every frame — that is acceptable.
  • Remove the transition property after the animation ends to avoid it interfering with future changes.
  • Framer Motion's layout prop implements FLIP automatically — use it instead of manual FLIP in React.
  • FLIP breaks if transform is already being used on the element for other purposes.

Revisions (0)

No revisions yet.