Svelte and SvelteKit course · Module 9: Transitions and Animations
List Animations (animate:flip)
In this lesson3
animate:flip
Animate position changes of elements in a list:
<script>
import { flip } from 'svelte/animate';
import { fade } from 'svelte/transition';
let items = $state([
{ id: 1, name: 'Ragnar' },
{ id: 2, name: 'Bjorn' },
{ id: 3, name: 'Ivar' }
]);
function shuffle() {
// $state is a deep proxy - sorting in place also updates the list
items.sort(() => Math.random() - 0.5);
}
</script>
<button onclick={shuffle}>Shuffle</button>
<ul>
{#each items as item (item.id)}
<li
animate:flip={{ duration: 300 }}
transition:fade
>
{item.name}
</li>
{/each}
</ul>Example: Sortable list
<script>
import { flip } from 'svelte/animate';
let warriors = $state([
{ id: 1, name: 'Ragnar', strength: 95 },
{ id: 2, name: 'Bjorn', strength: 88 },
{ id: 3, name: 'Ivar', strength: 70 }
]);
let sortBy = $state('name');
let sorted = $derived(
[...warriors].sort((a, b) =>
sortBy === 'name'
? a.name.localeCompare(b.name)
: b.strength - a.strength
)
);
</script>
<select bind:value={sortBy}>
<option value="name">By name</option>
<option value="strength">By strength</option>
</select>
<ul>
{#each sorted as warrior (warrior.id)}
<li animate:flip={{ duration: 300 }}>
{warrior.name} - {warrior.strength}
</li>
{/each}
</ul>crossfade - Transitions between lists
<script>
import { crossfade, fade } from 'svelte/transition';
import { flip } from 'svelte/animate';
const [send, receive] = crossfade({ fallback: fade });
let left = $state([1, 2, 3]);
let right = $state([4, 5]);
function moveRight(item) {
left = left.filter(i => i !== item);
right = [...right, item];
}
</script>
<div class="lists">
<ul>
{#each left as item (item)}
<li
in:receive={{ key: item }}
out:send={{ key: item }}
animate:flip
onclick={() => moveRight(item)}
>
{item}
</li>
{/each}
</ul>
<ul>
{#each right as item (item)}
<li
in:receive={{ key: item }}
out:send={{ key: item }}
animate:flip
>
{item}
</li>
{/each}
</ul>
</div>Code for this lesson: App.svelte
<script>
// animate: i flip - smooth element movement
import { flip } from 'svelte/animate';
import { fade } from 'svelte/transition';
let items = $state([
{ id: 1, name: 'Ragnar', rank: 1 },
{ id: 2, name: 'Bjorn', rank: 2 },
{ id: 3, name: 'Ivar', rank: 3 },
{ id: 4, name: 'Ubbe', rank: 4 },
{ id: 5, name: 'Hvitserk', rank: 5 }
]);
function shuffle() {
items = items
.map(item => ({ ...item, sort: Math.random() }))
.sort((a, b) => a.sort - b.sort)
.map((item, i) => ({ ...item, rank: i + 1 }));
}
function sortByName() {
items = [...items]
.sort((a, b) => a.name.localeCompare(b.name))
.map((item, i) => ({ ...item, rank: i + 1 }));
}
</script>
<main class="flip-demo">
<h1>animate:flip</h1>
<p class="subtitle">Smooth list element movement</p>
<div class="controls">
<button onclick={shuffle}>Shuffle</button>
<button onclick={sortByName}>Sort A-Z</button>
</div>
<div class="list">
{#each items as item (item.id)}
<div
class="item"
animate:flip={{ duration: 300 }}
transition:fade
>
<span class="rank">#{item.rank}</span>
<span class="name">{item.name}</span>
</div>
{/each}
</div>
</main>
<style>
.flip-demo {
font-family: 'Georgia', serif;
max-width: 400px;
margin: 0 auto;
padding: 2rem;
background: #1a0a0a;
color: #f7d5e8;
min-height: 100vh;
}
h1 {
color: #ff6b6b;
text-align: center;
}
.subtitle {
text-align: center;
color: #a87ca8;
}
.controls {
display: flex;
gap: 0.5rem;
margin: 1rem 0;
}
button {
flex: 1;
padding: 0.75rem;
background: #3a1a2a;
color: #f7d5e8;
border: 1px solid #ff6b6b;
border-radius: 4px;
cursor: pointer;
}
.list {
display: flex;
flex-direction: column;
gap: 0.5rem;
}
.item {
display: flex;
align-items: center;
gap: 1rem;
padding: 1rem;
background: rgba(255, 107, 107, 0.1);
border: 1px solid #ff6b6b;
border-radius: 8px;
}
.rank {
font-size: 1.5rem;
color: #ffd700;
min-width: 50px;
}
.name {
font-size: 1.1rem;
}
</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. What is animate:flip used for?