Styling Svelte — Svelte

Style di Svelte secara default scoped ke komponen. Scoped Style Teks ini berwarna merah p { color: red; } CSS p { color: red } hanya berlaku untuk di komponen…

Di Svelte, CSS sebuah komponen ditulis di tag <style> di file-nya sendiri, dan otomatis scoped: cuma mengenai elemen milik komponen itu. Bayangin papan menu kapur Warung Bu Sri. Bu Sri menghias papannya sendiri, dan coretannya gak pernah nyasar ke papan warung sebelah. Untuk menandai menu yang dipilih pembeli, dia menempel satu stiker "Pilihan" yang bisa dipindah dari menu ke menu. Kalau ada pengumuman untuk seluruh jalan, dia pasang spanduk yang dilihat semua orang. Di Svelte, papan itu <style> yang scoped, stiker yang pindah-pindah itu class:, dan spanduknya :global().

🧪 Tebakan cepat: di <style> ada aturan .aktif { border-color: #c2410c; }, tapi markup-nya gak pernah menyebut kelas aktif. Kelasnya ditempel dari JavaScript biasa: kartu.classList.add("aktif"). Bingkai kartunya jadi oranye atau tetap abu-abu? Jawabannya ada di bagian "Selektor yang gak dipakai dibuang".

Style yang scoped, dari dekat

Ini App.svelte Warung Bu Sri. Dia memasang Sapaan dari pelajaran Props, lalu tiga kartu menu yang bisa dipilih:

<script>
  import Sapaan from "./Sapaan.svelte"

  let menu = ["Nasi Goreng", "Mie Ayam", "Es Teh"]
  let dipilih = "Nasi Goreng"
</script>

<h1>Warung Bu Sri</h1>
<Sapaan nama="Sinta" />

{#each menu as nama (nama)}
  <button class="kartu" class:aktif={dipilih === nama} on:click={() => (dipilih = nama)}>{nama}</button>
{/each}

<p>Pilihanmu: {dipilih}</p>

<style>
  p { color: gray; }
  .kartu { margin-right: 6px; padding: 6px 12px; border: 2px solid #d1d5db; border-radius: 8px; background: white; }
  .aktif { border-color: #c2410c; background: #fff7ed; }
</style>

Svelte 4 mengubah style-nya jadi CSS ini (dipotong supaya pendek):

p.svelte-1l1nq9{color:gray}.kartu.svelte-1l1nq9{margin-right:6px;...}.aktif.svelte-1l1nq9{border-color:#c2410c;background:#fff7ed}

Dan DOM-nya jadi begini:

<h1>Warung Bu Sri</h1>
<p>Selamat datang, Sinta!</p>
<button class="kartu svelte-1l1nq9 aktif">Nasi Goreng</button>
<button class="kartu svelte-1l1nq9">Mie Ayam</button>
<button class="kartu svelte-1l1nq9">Es Teh</button>
<p class="svelte-1l1nq9">Pilihanmu: Nasi Goreng</p>

class:aktif: kelas yang nyala-mati

class:aktif={kondisi} memasang kelas aktif saat kondisinya true dan melepasnya saat false. Kelas lain di elemen itu gak terganggu.

Kejadian dipilih Kartu Nasi Goreng Kartu Mie Ayam
Awal "Nasi Goreng" kartu svelte-1l1nq9 aktif kartu svelte-1l1nq9
Klik Mie Ayam "Mie Ayam" kartu svelte-1l1nq9 kartu svelte-1l1nq9 aktif

Selektor yang gak dipakai dibuang

Compiler cuma membaca markup komponen itu. Selektor yang gak mungkin cocok dengan elemen mana pun dibuang dari CSS, dan compiler memberi warning:

Unused CSS selector ".aktif"

:global(): sengaja keluar dari scope

Kadang sebuah aturan memang harus berlaku di luar komponen: untuk body, atau untuk isi {@html} yang gak dapat kelas scope. Bungkus selektornya dengan :global(...):

<style>
  :global(body) { margin: 0; }
  :global(p) { color: gray; }
  .deskripsi :global(strong) { color: #c2410c; }
</style>

style: untuk satu properti

style:properti={nilai} mengisi satu properti CSS inline dari JavaScript:

<script>
  let ukuran = 24
  let tutup = false
</script>

<h1 style:font-size="{ukuran}px" style:color={tutup ? "gray" : null}>Warung Bu Sri</h1>

Latihan: paragraf biru

Kode awalnya <p>Teks berwarna biru</p>. Jawabannya:

<script>
  let active = true
</script>

<p class:active>Teks berwarna biru</p>

<style>
  p { color: gray; }
  .active { color: blue; }
</style>

Svelte 4 mencetak p.svelte-150wy2m{color:gray}.active.svelte-150wy2m{color:blue}, dan paragrafnya jadi <p class="svelte-150wy2m active">.

Svelte 5

<style> yang scoped, class:, style:, dan :global() ditulis sama persis di Svelte 5. Sejak Svelte 5.16, atribut class juga menerima objek: class={{ kartu: true, aktif: dipilih === nama }} artinya sama dengan class="kartu" class:aktif={dipilih === nama}.

⚠️ Jebakan yang sering ketemu

TL;DR: CSS di <style> komponen otomatis scoped: compiler menambah kelas seperti svelte-1l1nq9 ke tiap selektor dan ke elemen milik komponen itu, jadi style gak bocor ke komponen lain. class:aktif={kondisi} memasang kelas aktif saat kondisinya true dan melepasnya saat false; kalau nama variabelnya sama, cukup class:aktif. Selektor yang gak cocok dengan markup dibuang dengan warning Unused CSS selector, jadi kelas yang ditempel lewat JavaScript gak kena style. :global(selector) sengaja keluar dari scope, misalnya :global(body). style:font-size="{ukuran}px" mengisi satu properti dari data, dan null menghapusnya. Svelte 5 menulis semuanya sama. Latihannya: let active = true, <p class:active>Teks berwarna biru</p>, dan <style> dengan p { color: gray; } lalu .active { color: blue; }, sehingga paragrafnya biru.

Yang akan kamu pelajari