Skip to main content
Svelte Fundamentals
CHAPTER 17 Beginner

Svelte Transitions and Animations

Updated: May 18, 2026
5 min read

# CHAPTER 17

Svelte Transitions and Animations

1. Chapter Introduction

One of Svelte's most beloved features is its built-in animation and transition system. Unlike React and Vue that require third-party libraries, Svelte ships with fade, fly, slide, scale, draw, and crossfade transitions. No extra dependencies — just import and use.

2. Learning Objectives

  • Use transition:fade, transition:fly, transition:slide, transition:scale.
  • Use directional in: and out: transitions.
  • Animate lists with animate:flip.
  • Create custom transition functions.
  • Build an animated dashboard.

3. Built-in Transitions

svelte
1234567891011121314151617181920212223242526
<script>
  import { fade, fly, slide, scale, blur } from &#039;svelte/transition';
  let visible = true;
</script>

<button on:click={() => visible = !visible}>Toggle</button>

<!-- fade: opacity 0 to 1 -->
{#if visible}
  <div transition:fade={{ duration: 300 }}>Fades in and out</div>
{/if}

<!-- fly: moves AND fades -->
{#if visible}
  <div transition:fly={{ y: 50, duration: 400, easing: &#039;ease-out' }}>Flies from below</div>
{/if}

<!-- slide: reveals/collapses height -->
{#if visible}
  <div transition:slide={{ duration: 300 }}>Slides open and closed</div>
{/if}

<!-- scale: grows from zero -->
{#if visible}
  <div transition:scale={{ start: 0.5, duration: 300 }}>Scales in</div>
{/if}

4. In/Out Directional Transitions

Use in: for enter, out: for exit — different animations for each:
svelte
123456789101112
<script>
  import { fade, fly } from &#039;svelte/transition';
</script>

{#if visible}
  <div
    in:fly={{ x: -100, duration: 400 }}
    out:fade={{ duration: 200 }}
  >
    Flies in from left, fades out
  </div>
{/if}

5. List Animations with animate:flip

svelte
12345678910111213141516171819202122232425262728293031323334353637
<script>
  import { flip } from &#039;svelte/animate';
  import { fade } from &#039;svelte/transition';

  let items = [
    { id: 1, name: &#039;Item A' },
    { id: 2, name: &#039;Item B' },
    { id: 3, name: &#039;Item C' }
  ];

  function shuffle() {
    items = items.sort(() => Math.random() - 0.5);
  }

  function addItem() {
    items = [...items, { id: Date.now(), name: `Item ${items.length + 1}` }];
  }

  function remove(id) {
    items = items.filter(i => i.id !== id);
  }
</script>

<button on:click={shuffle}>Shuffle</button>
<button on:click={addItem}>Add</button>

<ul>
  {#each items as item (item.id)}
    <li
      animate:flip={{ duration: 300 }}
      transition:fade={{ duration: 200 }}
    >
      {item.name}
      <button on:click={() => remove(item.id)}>✕</button>
    </li>
  {/each}
</ul>

6. Transition Events

svelte
123456789
<div
  transition:fade
  on:introstart={() => console.log(&#039;Starting to show')}
  on:introend={() => console.log(&#039;Fully visible')}
  on:outrostart={() => console.log(&#039;Starting to hide')}
  on:outroend={() => console.log(&#039;Fully hidden')}
>
  Animated element
</div>

7. Custom Transition Functions

svelte
123456789101112131415161718
<script>
  function typewriter(node, { speed = 50 }) {
    const text = node.textContent;
    const duration = text.length * speed;

    return {
      duration,
      tick: (t) => {
        const i = Math.trunc(text.length * t);
        node.textContent = text.slice(0, i);
      }
    };
  }
</script>

{#if visible}
  <p transition:typewriter={{ speed: 30 }}>Hello, World!</p>
{/if}

8. Mini Project: Animated Dashboard

svelte
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
<script>
  import { fade, fly, scale } from &#039;svelte/transition';
  import { flip } from &#039;svelte/animate';

  let cards = [
    { id: 1, title: &#039;Revenue', value: '$24,500', icon: '💰', color: '#6366f1' },
    { id: 2, title: &#039;Users', value: '1,420', icon: '👥', color: '#10b981' },
    { id: 3, title: &#039;Orders', value: '384', icon: '🛍️', color: '#f59e0b' },
    { id: 4, title: &#039;Satisfaction', value: '94%', icon: '⭐', color: '#ef4444' }
  ];
  let notifications = [];
  let showNav = true;

  function addNotification(msg) {
    const id = Date.now();
    notifications = [...notifications, { id, msg }];
    setTimeout(() => {
      notifications = notifications.filter(n => n.id !== id);
    }, 3000);
  }
</script>

<div class="dashboard">
  {#if showNav}
    <aside transition:fly={{ x: -280, duration: 400 }}>
      <h2>Dashboard</h2>
      <nav>
        <a href="/">🏠 Home</a>
        <a href="/analytics">📊 Analytics</a>
      </nav>
    </aside>
  {/if}

  <main>
    <div class="stat-grid">
      {#each cards as card (card.id)}
        <div
          class="stat-card"
          animate:flip={{ duration: 300 }}
          in:scale={{ duration: 400 }}
          style="border-top: 4px solid {card.color}"
        >
          <span class="icon">{card.icon}</span>
          <div class="stat-value">{card.value}</div>
          <div class="stat-title">{card.title}</div>
        </div>
      {/each}
    </div>

    <button on:click={() => addNotification(&#039;Data refreshed!')}>Refresh</button>
  </main>
</div>

<!-- Floating notifications -->
<div class="notifications">
  {#each notifications as n (n.id)}
    <div class="toast" transition:fly={{ y: 60, duration: 300 }}>
      {n.msg}
    </div>
  {/each}
</div>

9. Common Mistakes

  • Using transitions on always-rendered elements: transition: only works when elements enter/leave the DOM (inside {#if} or {#each}). Use CSS animations for always-present elements.
  • animate:flip without a key: animate:flip requires a keyed {#each}{#each items as item (item.id)}.

10. MCQs

Question 1

What import provides Svelte's built-in transitions?

Question 2

What transition smoothly fades opacity?

Question 3

What transition moves an element AND fades it?

Question 4

What transition reveals height (like an accordion)?

Question 5

What animation smoothly repositions list items when order changes?

Question 6

What is the difference between transition: and in:/out:?

Question 7

What animate:flip requirement must be met?

Question 8

What does the tick function in a custom transition receive?

Question 9

What lifecycle events do transitions fire?

Question 10

Do Svelte animations require a third-party library?

11. Interview Questions

  • Q: What makes Svelte's animation system unique compared to React/Angular?
  • Q: How would you create a custom transition that types out text character by character?

12. Summary

Svelte's built-in animation system is one of its killer features. fade, fly, slide, scale cover 95% of UI animation needs without any dependencies. animate:flip makes list reordering silky smooth. And custom transition functions give you complete creative control — all in pure JavaScript.

13. Next Chapter Recommendation

In Chapter 18: Slots and Dynamic Components, we master Svelte's content composition system — using slots to build reusable layout components like Modals, Cards, and Tab panels.

Finish this Chapter

Save your progress on your learning path and prepare for coding interview challenges.

Discussion

Join the discussion

Log in or create a free account to participate.

Sort: ·