FLIP technique

플립 기법

A technique that measures an element's position before (First) and after (Last) a layout change, snaps it back with a transform (Invert), then animates that transform away (Play) — a layout jump becomes a smooth move.

Also known as: First Last Invert PlayShared element transition
···
html
<div class="items" id="items">
  <div class="item i1">1</div>
  <div class="item i2">2</div>
  <div class="item i3">3</div>
  <div class="item i4">4</div>
</div>
css
.items{position:absolute;inset:24% 10%;display:flex;gap:4%;align-items:flex-start}
.item{flex:1;aspect-ratio:1;border-radius:10px;display:grid;place-items:center;color:#fff;font:700 clamp(14px,4vmin,22px)/1 sans-serif}
.i1{background:var(--accent)}.i2{background:var(--accent-2)}.i3{background:var(--accent-3)}.i4{background:var(--accent)}
js
const box = document.getElementById('items');
const items = [...box.children];
let alt = false;
function flip(mutate) {
  const first = items.map((el) => el.getBoundingClientRect());
  mutate();
  const last = items.map((el) => el.getBoundingClientRect());
  items.forEach((el, i) => {
    const dx = first[i].left - last[i].left;
    const dy = first[i].top - last[i].top;
    if (dx || dy) {
      el.style.transition = 'none';
      el.style.transform = 'translate(' + dx + 'px, ' + dy + 'px)';
      requestAnimationFrame(() => {
        el.style.transition = 'transform .5s cubic-bezier(.2,.8,.2,1)';
        el.style.transform = '';
      });
    }
  });
}
function shuffle() {
  alt = !alt;
  const order = alt ? [3, 1, 2, 0] : [0, 1, 2, 3];
  flip(() => order.forEach((i) => box.appendChild(items[i])));
}
setInterval(shuffle, 2400);

Animating layout properties like top, left or width directly forces the browser to recompute layout every frame — slow. FLIP leaves the instant layout jump as-is, then uses a transform to shift the element back by exactly (position before − position after), and animates that transform down to zero — since only transform is touched, the GPU handles it and it stays smooth.

Used for list reordering, a card expanding from a grid into a modal, and drag-and-drop reordering — anywhere layout changes instantly and you want it to read as movement. The name was coined by Paul Lewis at Google.

The squares below reorder every 2.4s — under the hood, the DOM jumps instantly and each element's before/after position is measured and corrected with a transform.

When to use

Reach for it when an element's position or size jumps instantly due to a layout change. For a simple move that a plain transition already covers, you don't need FLIP.