#svelte #javascript #frontend

Day 9: Styles & Transitions

Welcome to Day 9. Svelte has the best styling story of any framework.

Scoped CSS

We saw this on Day 1. Styles in <style> blocks are scoped by default.

<p>I am red</p>

<style>
  p { color: red; } /* Only affects THIS p */
</style>

Global Styles

Use :global(...) to break out.

:global(body) {
  margin: 0;
}

Transitions

Svelte has a built-in transition engine.

<script>
  import { fade, fly, slide } from 'svelte/transition';
  let visible = $state(true);
</script>

<label>
  <input type="checkbox" bind:checked={visible} /> Show
</label>

{#if visible}
  <div transition:fade>
    I fade in and out!
  </div>
  
  <div transition:fly={{ y: 200, duration: 2000 }}>
    I fly up!
  </div>
{/if}

Challenge for Day 9

  1. Create a list of items (items = ['First', 'Second']).
  2. Render them.
  3. Add a button to Add Item.
  4. Add a generic โ€œDeleteโ€ button next to each item.
  5. Use transition:slide on the <li> elements.
  6. Animate the list reordering using animate:flip (import from svelte/animate).

Solution:

<script>
  import { slide } from 'svelte/transition';
  import { flip } from 'svelte/animate';
  
  let items = $state([1, 2, 3]);
</script>

<button onclick={() => items.push(items.length + 1)}>Add</button>

<ul>
  {#each items as item (item)}
    <li 
      transition:slide 
      animate:flip
      onclick={() => items = items.filter(i => i !== item)}
    >
      Item {item}
    </li>
  {/each}
</ul>

Beautiful interactions with almost zero code. Tomorrow, we finish the core concepts with Stores.