Transitions and Animations
Animating elements in and out of the DOM with Svelte's built-in transition directives.
읽는 데 2분
When {#if} removes an element from the DOM, it normally just disappears instantly. Svelte's transition: directive, paired with a small set of built-in transitions, animates that entrance and exit instead — without you writing keyframes or managing timers by hand.
<script>
import { fade } from 'svelte/transition';
let visible = $state(true);
</script>
<button onclick={() => (visible = !visible)}>Toggle</button>
{#if visible}
<p transition:fade>Now you see me.</p>
{/if}transition:fade runs the same animation on the way in and on the way out — the paragraph fades in when visible becomes true, and fades out (rather than vanishing) when it becomes false. Svelte delays actually removing the element from the DOM until the exit animation finishes.
Configuring a transition
Most built-in transitions accept an options object for duration, delay, and easing:
<script>
import { fly } from 'svelte/transition';
import { cubicOut } from 'svelte/easing';
let visible = $state(true);
</script>
{#if visible}
<div transition:fly={{ y: 20, duration: 300, easing: cubicOut }}>
Slides up into view.
</div>
{/if}svelte/transition ships several of these — fade, fly, slide, scale, draw (for SVG paths) — each animating a different CSS property or set of properties.
Different animations in and out
in: and out: let you use two different transitions instead of one shared one:
<script>
import { fly, fade } from 'svelte/transition';
</script>
{#if visible}
<div in:fly={{ y: -20 }} out:fade>
Flies in, fades out.
</div>
{/if}Animating list reordering
{#each} items that move position (say, after a sort) can animate smoothly into their new slot with the animate: directive, from svelte/animate:
<script>
import { flip } from 'svelte/animate';
let items = $state([1, 2, 3, 4]);
</script>
{#each items as item (item)}
<div animate:flip>{item}</div>
{/each}flip (short for "first, last, invert, play") measures each keyed item's position before and after an update and animates the difference — this only works correctly alongside a key, since Svelte needs to know which DOM node corresponds to which piece of data across the reorder.
Why this belongs to Svelte, not a library
Because the compiler already knows exactly when elements enter and leave the DOM, it can hook animations into that lifecycle directly, with no extra library watching the DOM for changes. That's also why these directives are so terse compared to typical animation libraries — transition:fade is doing the same job as import, ref, and effect wiring you'd write by hand elsewhere.