Svelte provides powerful built-in tools for creating smooth transitions and animations with minimal code.
Built-in Transitions
Fade Transition
svelte
<script>
import { fade } from 'svelte/transition';
let visible = true;
</script>
<button on:click={() => visible = !visible}>
Toggle
</button>
{#if visible}
<div transition:fade>
Fades in and out
</div>
{/if}Fly Transition
svelte
<script>
import { fly } from 'svelte/transition';
let visible = true;
</script>
{#if visible}
<p transition:fly="{{ y: -200, duration: 1000 }}">
Flies in from above
</p>
{/if}Slide Transition
svelte
<script>
import { slide } from 'svelte/transition';
let items = ['Item 1', 'Item 2', 'Item 3'];
</script>
{#each items as item, i (item)}
<div transition:slide|local>
{item}
</div>
{/each}Scale Transition
svelte
<script>
import { scale } from 'svelte/transition';
let visible = true;
</script>
{#if visible}
<div transition:scale|global>
Scales in and out
</div>
{/if}Transition Parameters
Common Parameters
svelte
<script>
import { fade, fly } from 'svelte/transition';
import { elasticOut } from 'svelte/easing';
let visible = true;
</script>
{#if visible}
<div
transition:fade={{
duration: 500,
delay: 100,
easing: elasticOut
}}
>
Custom fade
</div>
<div
transition:fly={{
x: 100,
y: 50,
duration: 800,
delay: 200
}}
>
Custom fly
</div>
{/if}In and Out Transitions
svelte
<script>
import { fade, fly } from 'svelte/transition';
let visible = true;
</script>
{#if visible}
<div
in:fade={{ duration: 500 }}
out:fly={{ y: 100 }}
>
Different transitions
</div>
{/if}Easing Functions
Built-in Easing
javascript
import {
quad,
cubic,
quart,
quint,
sine,
expo,
circ,
back,
elastic
} from 'svelte/easing';
// Each has in, out, and inOut variants
const { elasticIn, elasticOut, elasticInOut } = elastic;Custom Easing
javascript
// Custom bounce easing
function bounce(t) {
if (t < 1 / 2.75) {
return 7.5625 * t * t;
} else if (t < 2 / 2.75) {
return 7.5625 * (t -= 1.5 / 2.75) * t + 0.75;
} else if (t < 2.5 / 2.75) {
return 7.5625 * (t -= 2.25 / 2.75) * t + 0.9375;
} else {
return 7.5625 * (t -= 2.625 / 2.75) * t + 0.984375;
}
}Animations
Animate Directive
svelte
<script>
import { animate } from 'svelte/motion';
import { elasticOut } from 'svelte/easing';
let items = [
{ id: 1, name: 'Item 1' },
{ id: 2, name: 'Item 2' },
{ id: 3, name: 'Item 3' }
];
</script>
<button on:click={() => items = items.reverse()}>
Reverse
</button>
{#each items as item (item.id)}
<div
animate:flip={{
duration: d => Math.sqrt(d * 200),
easing: elasticOut
}}
>
{item.name}
</div>
{/each}Flip Animation
svelte
<script>
import { flip } from 'svelte/animate';
let items = [1, 2, 3, 4, 5];
function shuffle() {
items = items.sort(() => Math.random() - 0.5);
}
</script>
<button on:click={shuffle}>Shuffle</button>
<div class="container">
{#each items as item (item)}
<div animate:flip>{item}</div>
{/each}
</div>Spring Physics
Spring Store
svelte
<script>
import { spring } from 'svelte/motion';
const coords = spring({ x: 0, y: 0 }, {
stiffness: 0.1,
damping: 0.25
});
let size = spring(1);
</script>
<div
style="transform: translate({$coords.x}px, {$coords.y}px) scale({$size})"
>
Spring animation
</div>
<button on:click={() => size.set(2)}>Grow</button>
<button on:click={() => size.set(1)}>Shrink</button>Spring Parameters
javascript
// Stiff spring
spring(value, { stiffness: 1, damping: 1 });
// Bouncy spring
spring(value, { stiffness: 0.1, damping: 0.25 });
// Precision
spring(value, { precision: 0.01 });Tweened Values
svelte
<script>
import { tweened } from 'svelte/motion';
import { cubicOut } from 'svelte/easing';
const progress = tweened(0, {
duration: 1000,
easing: cubicOut
});
function start() {
progress.set(100);
}
</script>
<div>{Math.round($progress)}%</div>
<button on:click={start}>Start</button>Custom Transitions
Creating Custom Transitions
javascript
// transitions/glow.js
export function glow(node, { delay = 0, duration = 400 }) {
return {
delay,
duration,
css: (t, u) => {
return `
box-shadow: 0 0 ${t * 20}px rgba(0,0,0,0.5);
transform: scale(${1 + t * 0.1});
`;
}
};
}
export function blur(node, { delay = 0, duration = 400 }) {
return {
delay,
duration,
css: (t) => {
return `filter: blur(${(1 - t) * 10}px);`;
}
};
}Using Custom Transitions
svelte
<script>
import { glow, blur } from '../transitions';
let visible = true;
</script>
{#if visible}
<div transition:glow>
Glowing transition
</div>
<div transition:blur>
Blur transition
</div>
{/if}Complex Animations
Staggered Animation
svelte
<script>
import { fade } from 'svelte/transition';
let items = [1, 2, 3, 4, 5];
</script>
{#each items as item, i (item)}
<div
transition:fade={{
delay: i * 100,
duration: 300
}}
>
{item}
</div>
{/each}List Animation
svelte
<script>
import { slide } from 'svelte/transition';
let items = [];
function addItem() {
items = [...items, Date.now()];
}
function remove(item) {
items = items.filter(i => i !== item);
}
</script>
<button on:click={addItem}>Add</button>
{#each items as item (item)}
<div transition:slide|local>
{item}
<button on:click={() => remove(item)}>Remove</button>
</div>
{/each}Animation Best Practices
- 1Use CSS transforms - More performant than layout changes
- 2Keep durations short - 200-500ms for most transitions
- 3Use appropriate easing - Match the feeling you want
- 4Test performance - Use DevTools to check frame rates
- 5Consider accessibility - Respect prefers-reduced-motion
Svelte's animation system makes it easy to create smooth, performant animations.