0
0
Svelteframework~5 mins

Crossfade for list items in Svelte

Choose your learning style9 modes available
Introduction

Crossfade helps items smoothly change places or fade in and out in a list. It makes the list look nice and easy to follow.

When you add or remove items from a list and want a smooth animation.
When you reorder items in a list and want the movement to look natural.
When you want to highlight changes in a list without sudden jumps.
When you want to improve user experience by showing transitions between states.
Syntax
Svelte
import { crossfade } from 'svelte/transition';

const [send, receive] = crossfade({
  duration: 400,
  fallback(node, params) {
    return {
      duration: 400,
      css: t => `opacity: ${t}`
    };
  }
});

<ul>
  {#each items as item (item.id)}
    <li in:receive={{ key: item.id }} out:send={{ key: item.id }}>{item.text}</li>
  {/each}
</ul>

You import crossfade from svelte/transition.

It returns two functions: send and receive. Use them as out:send and in:receive on list items.

Examples
Basic crossfade with default settings.
Svelte
import { crossfade } from 'svelte/transition';

const [send, receive] = crossfade();

<ul>
  {#each items as item (item.id)}
    <li in:receive={{ key: item.id }} out:send={{ key: item.id }}>{item.text}</li>
  {/each}
</ul>
Custom duration for the crossfade animation.
Svelte
const [send, receive] = crossfade({ duration: 600 });
Custom fallback animation if crossfade can't find matching elements.
Svelte
const [send, receive] = crossfade({
  fallback(node) {
    return {
      duration: 300,
      css: t => `transform: scale(${t}); opacity: ${t}`
    };
  }
});
Sample Program

This Svelte component shows a list of fruits. You can add new fruits or remove existing ones. When items are added or removed, they smoothly crossfade in or out. The list items are keyboard accessible and the buttons have ARIA labels for screen readers.

Svelte
<script>
  import { crossfade } from 'svelte/transition';
  import { cubicOut } from 'svelte/easing';

  let items = [
    { id: 1, text: 'Apple' },
    { id: 2, text: 'Banana' },
    { id: 3, text: 'Cherry' }
  ];

  const [send, receive] = crossfade({
    duration: 500,
    easing: cubicOut,
    fallback(node) {
      return {
        duration: 500,
        css: t => `opacity: ${t}`
      };
    }
  });

  function removeItem(id) {
    items = items.filter(item => item.id !== id);
  }

  function addItem() {
    const newId = items.length ? Math.max(...items.map(i => i.id)) + 1 : 1;
    items = [...items, { id: newId, text: `Fruit ${newId}` }];
  }
</script>

<button on:click={addItem} aria-label="Add item">Add Item</button>

<ul>
  {#each items as item (item.id)}
    <li in:receive={{ key: item.id }} out:send={{ key: item.id }} tabindex="0">
      {item.text}
      <button on:click={() => removeItem(item.id)} aria-label="Remove {item.text}">Remove</button>
    </li>
  {/each}
</ul>

<style>
  ul {
    list-style: none;
    padding: 0;
    max-width: 300px;
    margin-top: 1rem;
  }
  li {
    background: #def;
    margin: 0.5rem 0;
    padding: 0.5rem 1rem;
    border-radius: 0.5rem;
    display: flex;
    justify-content: space-between;
    align-items: center;
  }
  button {
    background: #48a;
    color: white;
    border: none;
    border-radius: 0.3rem;
    padding: 0.3rem 0.6rem;
    cursor: pointer;
  }
  button:hover, button:focus {
    background: #357;
    outline: none;
  }
</style>
OutputSuccess
Important Notes

The crossfade animation runs in about 400-500 milliseconds by default.

Time complexity depends on the number of items but is usually fast enough for typical UI lists.

Common mistake: forgetting to add a unique key to each list item, which breaks the animation.

Use crossfade when you want smooth transitions between list states. For simple fade in/out, use fade transition instead.

Summary

Crossfade makes list items smoothly move or fade when added, removed, or reordered.

Use send and receive functions from svelte/transition on list items.

Always provide unique keys to list items for correct animation.