Kurs Svelte i SvelteKit · Moduł 2: Komponenty

Style w Svelte

2 min czytania ·
W tej lekcji5

Style w Svelte są domyślnie izolowane (scoped) - działają tylko w komponencie, w którym zostały zdefiniowane. To jak runiczne zaklęcie ochronne!

Style izolowane (scoped)

<h1>Tytuł w komponencie</h1>

<style>
  /* Ten styl dotyczy TYLKO tego komponentu */
  h1 {
    color: gold;
    font-size: 2rem;
  }
</style>

Svelte dodaje unikalne atrybuty do elementów:

<!-- Wynik w przeglądarce -->
<h1 class="svelte-abc123">Tytuł w komponencie</h1>

Style globalne

Czasem potrzebujesz stylów globalnych. Użyj :global():

<style>
  /* Tylko w tym komponencie */
  h1 {
    color: gold;
  }

  /* Globalnie - wszędzie w aplikacji */
  :global(body) {
    margin: 0;
    font-family: 'Norse', serif;
  }

  /* Global wewnątrz selektora */
  .container :global(h1) {
    color: silver;
  }
</style>

Dynamiczne klasy

Dyrektywa class:

<script>
  let isActive = $state(true);
  let isWarrior = $state(true);
  let status = $state('ready');
</script>

<!-- Dodaj klasę warunkowo -->
<div class:active={isActive}>
  Aktywny wojownik
</div>

<!-- Skrót gdy nazwa klasy = nazwa zmiennej -->
<div class:isWarrior>
  Wojownik
</div>

<!-- Wiele klas -->
<div
  class:active={isActive}
  class:warrior={isWarrior}
  class:status-ready={status === 'ready'}
>
  Wiking
</div>

Obiekt w atrybucie class (Svelte 5.16+)

Od Svelte 5.16 atrybut class przyjmuje też obiekt: klucz to nazwa klasy, a wartość mówi, czy ją dodać. Dokumentacja Svelte poleca tę formę w nowym kodzie, a dyrektywa class: nadal działa i spotkasz ją w wielu projektach:

<script>
  let isActive = $state(true);
  let isWarrior = $state(false);
</script>

<!-- To samo co class:active={isActive} class:warrior={isWarrior} -->
<div class={{ active: isActive, warrior: isWarrior }}>
  Wiking
</div>

<!-- Tablica łączy stałe klasy z warunkowymi -->
<div class={['card', isActive && 'active']}>
  Karta wojownika
</div>

Dynamiczny atrybut class

<script>
  let type = $state('warrior');
  let isActive = $state(false);
</script>

<div class="viking {type}">
  Typ: {type}
</div>

<!-- Wyrażenie ternarne -->
<div class={isActive ? 'active' : 'inactive'}>
  Status
</div>

Zmienne CSS (Custom Properties)

<script>
  let primaryColor = $state('#d4af37');
  let size = $state(24);
</script>

<div class="viking-badge" style="--color: {primaryColor}; --size: {size}px">
  <span>ᛏ</span>
</div>

<style>
  .viking-badge {
    color: var(--color);
    font-size: var(--size);
    padding: calc(var(--size) / 2);
  }
</style>

Style warunkowe inline

<script>
  let health = $state(75);
</script>

<div
  class="health-bar"
  style="width: {health}%; background: {health > 50 ? 'green' : 'red'}"
>
  {health}%
</div>
Kod do tej lekcji: App.svelte
<script>
  // Styles in Svelte - isolated like the nine worlds
  let isElite = $state(true);
  let theme = $state('dark');
</script>

<div class="demo" class:elite={isElite}>
  <h1>Styles in Svelte</h1>

  <p>Styles are <strong>scoped</strong> by default!</p>

  <div class="controls">
    <label>
      <input type="checkbox" bind:checked={isElite} />
      Elite warrior (class:elite)
    </label>

    <select bind:value={theme}>
      <option value="dark">Dark</option>
      <option value="light">Light</option>
    </select>
  </div>

  <div class="card {theme}">
    <p>Dynamic class: {theme}</p>
  </div>
</div>

<style>
  .demo {
    font-family: 'Georgia', serif;
    max-width: 500px;
    margin: 2rem auto;
    padding: 2rem;
    background: #1a0f0a;
    color: #e8d5b7;
    border-radius: 8px;
  }

  h1 {
    color: #d4af37;
  }

  /* Conditional class */
  .demo.elite {
    border: 3px solid #ffd700;
    box-shadow: 0 0 20px rgba(255, 215, 0, 0.3);
  }

  .controls {
    margin: 1rem 0;
    padding: 1rem;
    background: rgba(0,0,0,0.3);
    border-radius: 4px;
  }

  label {
    display: block;
    margin-bottom: 0.5rem;
  }

  select {
    padding: 0.5rem;
    background: #2c1810;
    color: #e8d5b7;
    border: 1px solid #d4af37;
    border-radius: 4px;
  }

  .card {
    padding: 1rem;
    border-radius: 4px;
    margin-top: 1rem;
  }

  .card.dark {
    background: #0a0a0a;
    color: #e8d5b7;
  }

  .card.light {
    background: #f5f5f5;
    color: #1a1a1a;
  }
</style>

Hasła z dokumentacji w tej lekcji

Widzisz błąd w tej lekcji?

Sprawdź się

Odpowiedz na pytania z tej lekcji. Wybierz odpowiedź, a od razu zobaczysz, czy jest poprawna.

  1. 1. Co oznacza, że style w Svelte są 'scoped' (izolowane)?

  2. 2. Jak zdefiniować globalny styl w komponencie Svelte?

  3. 3. Jak użyć skróconej składni class: gdy nazwa klasy jest taka sama jak nazwa zmiennej?

Zadania praktyczne w grze

  • Edytor kodu

    Uzupełnij kod, aby klasa 'active' była dodana gdy isActive jest true

Przydatne artykuły