Lesson 12 / 25
Transitions and Animations
Animate elements entering, leaving and moving.
transition:, in:, out: and animate:
Svelte ships transition functions in svelte/transition such as fade, fly, slide, scale, blur and draw. transition:fade plays when an element enters or leaves the DOM because of a block ({#if}, {#each}), while in: and out: set different effects for each direction. Parameters such as { duration: 200, y: 20 } and easing functions from svelte/easing customise them. Transitions are local by default: they only play when their own block changes; add |global to play when a parent block changes too. animate:flip from svelte/animate smoothly moves items in a keyed each block when the order changes. For animated numbers, svelte/motion provides tweened and spring helpers (Svelte 5 adds Tween and Spring classes; check the docs for your version).
Fly in, fade out, flip on reorder
Toasts that animate.
<script lang="ts">
import { fly, fade } from 'svelte/transition';
import { flip } from 'svelte/animate';
import { cubicOut } from 'svelte/easing';
let toasts = $state<{ id: number; text: string }[]>([]);
let nextId = 1;
function push(text: string) {
const id = nextId++;
toasts.unshift({ id, text });
setTimeout(() => (toasts = toasts.filter((t) => t.id !== id)), 3000);
}
</script>
<button onclick={() => push('Saved')}>Save</button>
<ul class="toasts">
{#each toasts as toast (toast.id)}
<li
in:fly={{ y: -20, duration: 250, easing: cubicOut }}
out:fade={{ duration: 150 }}
animate:flip={{ duration: 200 }}
>
{toast.text}
</li>
{/each}
</ul>Respect reduced motion
Check the prefers-reduced-motion media query and shorten or skip durations for users who ask for less motion.
Quick check: Which requirement applies to animate:flip?
- It only works inside {#await}
- It must be on an element directly inside a keyed each block
- It needs a global CSS animation
- It only animates opacity
Answer
It must be on an element directly inside a keyed each block — flip relies on keys to track positions.