Motion · GSAP-style

Flip layout animation

Change the layout however you like — toggle a class, reorder nodes, filter items — and .flip() animates every element from where it was to where it is now.

First, Last, Invert, Play

Flip records each element's position and size (first), runs your change, measures again (last), applies the inverse transform so nothing seems to move, then tweens the transform back to zero (play). The browser only animates transform, so it stays smooth even for large lists.

Use the one-call form $('.card').flip(change, options), or the two-step GSAP form $.Flip.getState() … $.Flip.from(state, options) when the change happens somewhere else. It returns a timeline you can await.

Live · Shuffle, filter and switch layout

1 · Mug
2 · Tee
3 · Cap
4 · Bag
5 · Pin
6 · Pen
7 · Hat
8 · Mat
View the source for this demo
HTML
<div class="row">
  <button type="button" id="fl-shuffle">Shuffle</button>
  <button type="button" id="fl-layout" aria-pressed="false">List view</button>
  <button type="button" id="fl-odd" aria-pressed="false">Hide odd tiles</button>
</div>
<div id="fl-grid" class="fl-grid" style="margin-top:14px">
  <div class="fl-tile">1 · Mug</div><div class="fl-tile">2 · Tee</div><div class="fl-tile">3 · Cap</div><div class="fl-tile">4 · Bag</div>
  <div class="fl-tile">5 · Pin</div><div class="fl-tile">6 · Pen</div><div class="fl-tile">7 · Hat</div><div class="fl-tile">8 · Mat</div>
</div>
JavaScript
const flip = change => $('#fl-grid .fl-tile').flip(change, { duration: 0.6, ease: 'power2.inOut', stagger: 0.02 });

$('#fl-shuffle').on('click', () => flip(() => {
  const tiles = $('#fl-grid .fl-tile').get().sort(() => Math.random() - 0.5);
  $('#fl-grid').append(tiles);
}));
$('#fl-layout').on('click', function () {
  const on = this.getAttribute('aria-pressed') !== 'true';
  $(this).attr('aria-pressed', on);
  flip(() => $('#fl-grid').toggleClass('list', on));
});
$('#fl-odd').on('click', function () {
  const on = this.getAttribute('aria-pressed') !== 'true';
  $(this).attr('aria-pressed', on);
  flip(() => $('#fl-grid .fl-tile').each(function () {
    this.hidden = on && parseInt(this.textContent, 10) % 2 === 1;
  }));
});

More examples

Two-step form

JavaScript
const state = $.Flip.getState('.card');
$('#grid').toggleClass('list');                 // any DOM change
await $.Flip.from(state, { duration: .6, ease: 'power2.inOut', stagger: .03 });

API

$.Flip.getState(targets) · $.Flip.from(state, { duration, ease, stagger, absolute, scale, onEnter, onLeave }) · $(sel).flip(changeFn, vars)

Animate any layout change.

Reference: jskjs.flip.js →

Migrating

Coming from GSAPFlip.getState() / Flip.from() keep their names under $.Flip. The extra .flip(change) shorthand records, changes and plays in one call.

Related features