Svelte and SvelteKit course · Module 9: Transitions and Animations
Ragnarok - Transitions and Animations
In this lesson5
Welcome to the field of Ragnarok! Just as the twilight of the gods brings spectacular transformations, Svelte offers powerful tools for animations.
Built-in transitions
<script>
import { fade, fly, slide, scale, blur, draw } from 'svelte/transition';
let visible = $state(true);
</script>
<button onclick={() => visible = !visible}>Toggle</button>
{#if visible}
<div transition:fade>Fade</div>
<div transition:fly={{ y: 200 }}>Fly</div>
<div transition:slide>Slide</div>
<div transition:scale>Scale</div>
<div transition:blur={{ amount: 10 }}>Blur</div>
{/if}Transition parameters
<script>
import { fly } from 'svelte/transition';
import { cubicOut } from 'svelte/easing';
</script>
<div transition:fly={{
x: 100, // X offset
y: -50, // Y offset
duration: 500, // duration (ms)
delay: 100, // delay (ms)
easing: cubicOut // easing function
}}>
Animated!
</div>in: and out: - Separate animations
<script>
import { fade, fly } from 'svelte/transition';
let visible = $state(true);
</script>
{#if visible}
<div
in:fly={{ y: -50, duration: 300 }}
out:fade={{ duration: 200 }}
>
Flies in, fades out smoothly
</div>
{/if}Local and global transitions
In Svelte 5 transitions are local by default: they only play when the block they directly belong to (for example that {#if}) appears or disappears, not when a parent block changes. If you want them to play every time, add the |global modifier:
<div transition:fade|global>Always animated</div>Transitions also do not play on the first render of the page - they only animate later changes.
Transition events
You handle transition events like any other event in Svelte 5 - with on... attributes:
<div
transition:fade
onintrostart={() => console.log('Intro start')}
onintroend={() => console.log('Intro end')}
onoutrostart={() => console.log('Outro start')}
onoutroend={() => console.log('Outro end')}
>
Animated element
</div>Ragnarok is a spectacle of transformation - just like your animations!
Code for this lesson: App.svelte
<script>
// Ragnarok - End and beginning, transitions between states
// transition: - built-in transitions
import { fade, fly, slide, scale, blur } from 'svelte/transition';
let visible = $state(true);
let selectedTransition = $state('fade');
</script>
<main class="ragnarok">
<h1>Ragnarök - Transitions</h1>
<p class="subtitle">Built-in Svelte transitions</p>
<section>
<h2>Choose transition</h2>
<div class="options">
{#each ['fade', 'fly', 'slide', 'scale', 'blur'] as t}
<button
class:active={selectedTransition === t}
onclick={() => selectedTransition = t}
>
{t}
</button>
{/each}
</div>
<button class="toggle" onclick={() => visible = !visible}>
{visible ? 'Hide' : 'Show'}
</button>
</section>
<div class="demo-area">
{#if visible}
{#if selectedTransition === 'fade'}
<div class="box" transition:fade>
fade - smooth fading
</div>
{:else if selectedTransition === 'fly'}
<div class="box" transition:fly={{ y: 100, duration: 500 }}>
fly - flies in from below
</div>
{:else if selectedTransition === 'slide'}
<div class="box" transition:slide>
slide - sliding
</div>
{:else if selectedTransition === 'scale'}
<div class="box" transition:scale={{ start: 0.5 }}>
scale - scaling
</div>
{:else if selectedTransition === 'blur'}
<div class="box" transition:blur={{ amount: 10 }}>
blur - blur
</div>
{/if}
{/if}
</div>
</main>
<style>
.ragnarok {
font-family: 'Georgia', serif;
max-width: 500px;
margin: 0 auto;
padding: 2rem;
background: linear-gradient(135deg, #1a0a0a 0%, #2a0a1a 100%);
color: #f7d5e8;
min-height: 100vh;
}
h1 {
color: #ff6b6b;
text-align: center;
}
.subtitle {
text-align: center;
color: #a87ca8;
}
section {
background: rgba(255, 107, 107, 0.1);
border: 1px solid #ff6b6b;
border-radius: 8px;
padding: 1rem;
margin: 1rem 0;
}
h2 {
color: #ff6b6b;
font-size: 1rem;
margin-top: 0;
}
.options {
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
margin-bottom: 1rem;
}
button {
padding: 0.5rem 1rem;
background: #3a1a2a;
color: #f7d5e8;
border: 1px solid #ff6b6b;
border-radius: 4px;
cursor: pointer;
}
button.active {
background: #ff6b6b;
color: #1a0a0a;
}
.toggle {
width: 100%;
padding: 0.75rem;
font-size: 1.1rem;
}
.demo-area {
min-height: 150px;
display: flex;
align-items: center;
justify-content: center;
margin-top: 1rem;
}
.box {
padding: 2rem;
background: rgba(255, 107, 107, 0.2);
border: 2px solid #ff6b6b;
border-radius: 8px;
text-align: center;
color: #ffd700;
}
</style>Docs entries used in this lesson
Spotted a mistake in this lesson?
Check yourself
Answer the questions from this lesson. Pick an answer to see right away whether it is correct.
1. Which built-in transitions does Svelte offer?
2. How do you set different animations for entering and leaving?
Hands-on tasks in the game
- Code editor
Complete the code so the element appears with a fade effect