Simple Animated Page Transition in Svelte
- 2 minutes read
Adding a page transition can make navigation on some apps look smoother and feel more fluid.
In this example, we’ll build a simple and customizable page transition for a SvelteKit app.
Let’s begin by creating a new Transition.svelte
component:
<!-- Transition.svelte -->
<script>
import { onMount } from 'svelte';
import { fly } from 'svelte/transition';
export let refresh = ``;
</script>
{#key refresh}
<!-- You can modify the in:fly and out:fly attributes to your liking! -->
<div in:fly={{ delay: 100, duration: 200, y: -10, }} out:fly={{ duration: 100, y: 10, }}>
<slot />
</div>
{/key}
Then, in our __layout.svelte
file, we can place the content we want to animate within our Transition.svelte
component.
The following example assumes that Transition.svelte
is placed in $lib/components/Transition.svelte
.
This example also animates everything below the navbar, but you can position the <Transition>
component however you want:
<!-- __layout.svelte -->
<script context="module">
export const load = async ({ page }) => ({
props: {
key: page.path,
},
});
</script>
<script>
import Transition from '$lib/components/Transition.svelte';
export let key;
</script>
<nav>
<p>This content will not be animated!</P>
</nav>
<Transition>
<!-- Everything inside this transition component will be animated! -->
<!-- In this example, that encompasses all the page contents besides the navbar. -->
<slot />
</Transition>
If you’ve reset your layout in certain parts of your app using the __layout.reset.svelte
file, then you might want to check whether you want to animate pages that descend from that layout reset as well.
Page transition accessibility considerations
The following Transition.svelte
variant disables the page transition for users that explicitly prefer reduced motion in their browser settings:
<!-- Transition.svelte -->
<script>
import { onMount } from 'svelte';
import { fly } from 'svelte/transition';
export let refresh = ``;
let animations = false;
onMount(() => animations = window.matchMedia(`(prefers-reduced-motion: reduce)`) === true || window.matchMedia(`(prefers-reduced-motion: reduce)`).matches !== true);
</script>
{#key refresh}
{#if !!animations}
<!-- You can modify the in:fly and out:fly attributes to your liking! -->
<div in:fly={{ delay: 100, duration: 200, y: -10, }} out:fly={{ duration: 100, y: 10, }}>
<slot />
</div>
{:else}
<slot />
{/if}
{/key}
To improve your app’s accessibility, I strongly suggest opting for this modified Transition.svelte
.
Conclusion
I hope you enjoyed this quick little tutorial on how to add page transitions to your SvelteKit app, but I also hope that you implemented the reduced motion check!
I lastly want to note that Svelte offers many
other transitions besides fly
that you can tinker with.
Anyway, thanks for reading.