Skip to content

Transitions & Animations

Transitions animate elements entering and leaving

Section titled “Transitions animate elements entering and leaving”

When an element is added to or removed from the DOM (via {#if}, {#each}, etc.), a transition animates that change. Apply one with the transition: directive, using a built-in from svelte/transition:

<script>
import { fade } from 'svelte/transition';
let visible = $state(true);
</script>
<button onclick={() => (visible = !visible)}>toggle</button>
{#if visible}
<p transition:fade>Fades in when added, fades out when removed</p>
{/if}

transition: applies to both enter and leave. When you want different animations for each, use in: and out: separately:

<script>
import { fly, fade } from 'svelte/transition';
</script>
{#if visible}
<div in:fly={{ y: 20 }} out:fade>Flies in, fades out</div>
{/if}

The built-ins include fade, fly, slide, scale, blur, and draw (for SVG). Each accepts parameters — duration, delay, easing, and transition-specific options like fly’s x/y:

<p transition:fly={{ y: 50, duration: 400, delay: 100 }}></p>
flowchart LR
  add["element added to DOM"] --> intro["in: / transition: plays the intro"]
  remove["element removed"] --> outro["out: / transition: plays the outro"]
  outro --> gone["element leaves after the animation"]
Enter and leave transitions

Transitions handle add/remove, but not movement. When items in a keyed {#each} reorder, the animate: directive smoothly slides them to their new positions. The built-in flip (First-Last-Invert-Play) from svelte/animate does exactly this:

<script>
import { flip } from 'svelte/animate';
let items = $state([1, 2, 3, 4]);
function shuffle() { items = items.toSorted(() => Math.random() - 0.5); }
</script>
<button onclick={shuffle}>shuffle</button>
{#each items as item (item)}
<div animate:flip={{ duration: 300 }}>{item}</div>
{/each}

animate: requires a keyed each block — the key (item) is how Svelte knows which element moved where. Combine animate:flip with transition: on the same list to animate additions, removals, and reordering all at once.

What does the `transition:` directive animate?
How do you use different animations for enter vs leave?
What does `animate:flip` do, and what does it require?
Where do the built-in transitions like `fly` come from?