Dynamic elements - .appear

A MutationObserver watches the document for insertions. Any added element carrying .appear plays its entrance immediately - pagination rows rendered after a fetch, modals, list items, everything.

Demo - real insertions

Replay works the same way

The replay wrapper below removes its child and re-inserts it. To the engine that is indistinguishable from app code mounting new content:

re-mounted on every replay

Rules of thumb: without .appear, inserted elements are ignored (no surprise animations). Non-text elements carrying .scroll are owned by their ScrollTrigger instead and .appear yields to it. Each element animates once per mount - re-inserting the same node replays it, since the guard is per engine run.

js
const row = document.createElement('li')
row.className = 'appear spawn-left'
list.appendChild(row)   // entrance plays automatically

.leave - animated exits

Adding .leave to an element teaches the engine its exit: on insertion the element (and its spawn's from state) is captured; when it's later removed, a ghost replays the entrance in reverse while a spacer holds the layout steady - so surrounding content never jumps.

text
row.className = 'appear leave spawn-left'
list.appendChild(row)
// later:
row.remove()   // slides back out, layout held by a spacer

Combine with any spawn class - the leave animation is simply that spawn played in reverse from the element's captured state.

.flip - FLIP layout morph

.flip is Vanilla FLIP: on insertion the engine captures the element's document-relative bounds (flipPos), then on the next layout change each .flip under the mutated scope slides from its old to new position (gsap.fromTo x/y). Great for reorders, filters, or masonry shuffles - no manual Flip plugin call needed.

A
B
C

Each box has .flip + any spawn - any DOM reorder slides from old to new position.

html
<div id="list" class="flex gap-3">
  <div class="flip spawn-up">A</div>
  <div class="flip spawn-up">B</div>
  <div class="flip spawn-up">C</div>
</div>

<script>
  // any DOM reorder triggers FLIP - MutationObserver in Listeners.js:272 handles it
  list.appendChild(list.firstElementChild) // A → end, B and C slide to fill
</script>

Add .flip alongside any spawn (flip spawn-up). The engine guards re-entrancy (flipping WeakSet) and kills in-flight tweens so rapid shuffles don't compound.