Chapter Custom Properties di section values telah membahas mekanismenya: nama berawalan --, dibaca lewat var(), dan mewarisi ke turunan. Chapter ini menempatkan mekanisme itu dalam kerangka arsitektur. Ketika custom properties dipakai tanpa rancangan, variabel bermunculan di mana saja dengan konvensi yang berbeda-beda; dengan rancangan, kita mendapatkan dua lapis yang tugasnya terpisah — lapis token global sebagai sumber kebenaran desain, dan lapis variabel lokal komponen sebagai antarmuka yang dapat ditimpa dari luar. Chapter ini membahas pembagian dua lapis tersebut, pola fallback pada var(), dan penutup singkat tentang @property yang memberi tipe pada variabel.

Dua Lapis Variabel: Token dan Lokal Komponen #

Lapis pertama adalah token global di :root seperti pada Chapter Design Tokens . Lapis kedua adalah variabel yang dimiliki satu komponen, didefinisikan pada class komponen itu sendiri:

:root {
  --warna-aksen: rgb(2, 132, 199);
}
.kartu {
  /* Variabel lokal — antarmuka komponen */
  --kartu-aksen: var(--warna-aksen);
  --kartu-latar: rgb(255, 255, 255);

  background-color: var(--kartu-latar);
  border: 1px solid rgb(226, 232, 240);
  border-left: 4px solid var(--kartu-aksen);
  border-radius: 8px;
  padding: 16px;
  color: rgb(15, 23, 42);
}

Mari kita telaah arsitekturnya:

  1. Baris 1–3 (:root): token global --warna-aksen — satu sumber kebenaran warna aksen bagi seluruh halaman.
  2. Baris 5–7 (.kartu): komponen mendefinisikan variabel lokal --kartu-aksen yang bawaannya merujuk token global. Komponen tidak pernah membaca token langsung di properti; semua properti membaca variabel lokal.
  3. Baris 8–9: properti visual (background-color, border-left) hanya menyebut variabel lokal, sehingga seluruh tampilan aksen kartu bermuara pada satu nama.

Perbedaan lapisan ini terasa saat komponen divariasikan. Varian tidak menimpa properti, melainkan menimpa variabel lokalnya:

css
.kartu--sukses {
  --kartu-aksen: rgb(22, 163, 74);
}

Satu baris mengubah border kiri dan warna label di dalam kartu sekaligus, karena keduanya membaca --kartu-aksen yang mewarisi ke turunannya. Inilah keuntungan variabel sebagai antarmuka: variasi menjadi data (nilai variabel), bukan aturan baru yang menambah jumlah selector.

Hasil di Browser:

text
Kartu bawaan tampil dengan border kiri biru rgb(2, 132, 199) dari
token --warna-aksen dan latar putih dari --kartu-latar.
Kartu varian --sukses memiliki border kiri hijau rgb(22, 163, 74)
karena menimpa satu variabel lokal --kartu-aksen.
Label di dalam kartu sukses ikut hijau — variabel lokal mewarisi
ke turunan komponen.
Notifikasi galat tampil merah rgb(185, 28, 28) dari fallback var()
karena --warna-kesalahan tidak didefinisikan di mana pun.

Fallback dan @property Singkat #

Pola var(--x, nilai-cadangan) menjaga komponen tetap tampil wajar saat variabel belum disetel — berguna ketika komponen dikirim terpisah dari temanya:

css
.notifikasi {
  color: var(--warna-kesalahan, rgb(185, 28, 28));
}

Bila --warna-kesalahan tersedia (misalnya didefinisikan tema), fallback diabaikan; bila tidak, merah dipakai. Dengan begitu komponen memiliki nilai default yang terdokumentasi di tempatnya, dan tema cukup menyediakan penimpa bila memang mau.

Pembagian kerjanya dapat diringkas demikian: tema bekerja pada token global, varian bekerja pada variabel lokal, dan komponen tidak pernah melompati salah satu lapis itu. Bila varian langsung menulis nilai warna mentah, warna tersebut terlepas dari tema; bila tema menimpa variabel lokal komponen, tema tahu terlalu banyak detail internal komponen. Disiplin sederhana ini membuat pertanyaan “di mana nilai ini berasal?” selalu punya jawaban yang bisa ditebak.

Berkas Sumber

Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.

contoh-var-komponen.css

Unduh berkas
css
:root {
  --warna-aksen: rgb(2, 132, 199);
}
.kartu {
  /* Variabel lokal — antarmuka komponen */
  --kartu-aksen: var(--warna-aksen);
  --kartu-latar: rgb(255, 255, 255);

  background-color: var(--kartu-latar);
  border: 1px solid rgb(226, 232, 240);
  border-left: 4px solid var(--kartu-aksen);
  border-radius: 8px;
  padding: 16px;
  color: rgb(15, 23, 42);
}
.kartu--sukses {
  --kartu-aksen: rgb(22, 163, 74);
}
.kartu__label {
  color: var(--kartu-aksen);
  font-size: 12px;
  font-weight: 700;
}
.notifikasi {
  color: var(--warna-kesalahan, rgb(185, 28, 28));
  font-size: 14px;
}