Perhatikan stylesheet yang terus tumbuh: warna aksen #1f6f54 bisa tertulis di belasan aturan sekaligus — pada border tombol, warna link, latar badge, dan warna judul. Begitu keputusan desain berubah, kita harus memburu setiap baris itu satu per satu, dan satu nilai yang terlewat cukup untuk membuat tampilan tidak konsisten. CSS custom properties menyelesaikan masalah ini: nilai disimpan sekali dengan nama yang kita pilih, lalu dipakai ulang di mana pun. Pada chapter ini kita mempelajari cara mendeklarasikannya, aturan penamaannya, dan perbedaannya dengan variabel preprocessor.

Deklarasi Variabel Pertama #

Custom property ditulis seperti property biasa, tetapi namanya diawali dua tanda hubung, dan isinya adalah nilai yang ingin kita simpan. Konvensi yang paling lazim adalah mendeklarasikannya pada :root agar tersedia untuk seluruh halaman. Selector :root adalah pseudo-class yang memilih elemen paling atas dokumen — html — dengan specificity setara satu class, sehingga cocok menjadi “rak” tempat semua token desain disimpan.

css
:root {
  --warna-aksen: #1f6f54;
  --jarak-kartu: 16px;
  --radius-kartu: 12px;
}

.tombol-utama {
  background-color: var(--warna-aksen);
  padding: var(--jarak-kartu);
  border-radius: var(--radius-kartu);
}

Mengubah nilai --warna-aksen pada satu tempat langsung mengubah tombol tanpa menyentuh aturan .tombol-utama lagi.

Mari kita telaah pola di atas:

  1. :root { ... }: blok tempat variabel dideklarasikan. Semua token desain halaman biasanya berkumpul di sini.
  2. --warna-aksen: #1f6f54;: satu deklarasi custom property. Nama diawali --, nilai ditulis setelah titik dua seperti property biasa.
  3. var(--warna-aksen): fungsi var() membaca isi variabel dan menggantikan nilai property dengan isinya. Detail lengkapnya kita bedah pada chapter berikutnya.

Lencana, kartu, dan tombol berikut berbagi satu set token dari :root yang sama:

Buka DevTools pada demo ini, ubah nilai --warna-aksen pada :root, dan lihat ketiga elemen berubah seketika — inilah bukti variabel benar-benar hidup di browser.

Aturan Penamaan Variabel #

Browser menerapkan beberapa aturan tegas untuk nama custom property, dan ada satu konvensi yang sebaiknya kita ikuti sejak baris pertama:

AturanPenjelasanContoh
Wajib diawali dua tanda hubungTanpa awalan --, browser menganggapnya property biasa yang tidak dikenal dan membuangnya--warna-aksen
Case-sensitive--Warna-Aksen dan --warna-aksen adalah dua variabel berbedapilih satu gaya, konsisten
Kebab-case adalah konvensihuruf kecil dipisah tanda hubung, sejalan dengan konvensi penamaan class--jarak-kartu
Angka boleh, spasi tidaknama boleh memuat angka dan tanda hubung, tetapi tidak boleh mengandung spasi--spasi-2

Nama terbaik adalah nama yang menggambarkan peran nilainya, misalnya --warna-aksen, bukan --hijau. Pemilihan nama yang bermakna akan kita rapikan menjadi konvensi lengkap pada chapter Naming Conventions di akhir section ini.

Nilai Apa Saja yang Bisa Disimpan #

Isi custom property tidak dibatasi satu token. Nilainya bisa berupa warna, panjang, daftar nilai utuh untuk shorthand, hingga sebagian deklarasi — browser menyimpannya apa adanya dan baru menafsirkannya saat var() memakainya:

css
:root {
  --elevasi-2: 0 4px 12px rgba(15, 40, 30, 0.16);
  --border-kartu: 1px solid #d9d2c0;
  --font-teks: system-ui, sans-serif;
}

.kartu-artikel {
  border: var(--border-kartu);
  box-shadow: var(--elevasi-2);
  font-family: var(--font-teks);
}

Kita sebenarnya sudah pernah melihat pola ini pada chapter Box Shadow saat menyusun token elevasi; saat itu var() baru dicicipi, dan sekarang pola itu menjadi standar penulisan kita.

Custom Properties vs Variabel Preprocessor #

Sebelum custom properties ada, nilai yang dipakai ulang biasanya dikelola oleh preprocessor seperti Sass. Keduanya sering disebut “variabel”, tetapi tempat hidupnya berbeda:

AspekCustom propertiesVariabel preprocessor
Tempat hidupBrowser, saat halaman berjalanSaat proses build, sebelum CSS sampai ke browser
DinamisNilai bisa berubah lewat media query, state :hover, atau JavaScriptNilai terkunci setelah dikompilasi
Cascade dan inheritanceMengikuti aturan cascade dan mewarisi ke elemen anakTidak mengenal cascade sama sekali
InspeksiTerlihat dan bisa diubah langsung di DevToolsTidak ada di DevTools karena sudah disubstitusi

Karena custom properties adalah bagian resmi dari CSS, tidak ada langkah build yang wajib untuk memakainya. Preprocessor tetap berguna untuk kebutuhan lain, tetapi untuk nilai yang perlu berubah saat halaman berjalan, variabel native-lah alat yang tepat.

Ringkasan #

Custom properties menyimpan nilai CSS dengan nama berawalan --, biasanya dideklarasikan pada :root, dan dibaca dengan var(). Namanya case-sensitive, mengikuti konvensi kebab-case, dan isinya bisa berupa nilai apa pun — dari satu warna hingga daftar bayangan utuh. Berbeda dari variabel preprocessor, variabel ini hidup di browser sehingga dinamis dan bisa diperiksa di DevTools. Chapter berikutnya membedah var() secara tuntas: nilai cadangan, pewarisan, dan apa yang terjadi saat nilai variabel tidak valid.