Palet warna yang terorganisir adalah bagian dari design tokens yang paling sering dilihat pengguna. Tanpa struktur, warna bermunculan sebagai nilai mentah yang mirip tetapi tidak pernah persis sama — lima abu-abu berbeda untuk tugas yang sama. Kita membangun palet sebagai ramp: satu hue yang disusun menjadi tingkatan terang ke gelap dengan nomor 50 hingga 900, ditambah ramp netral untuk teks dan garis. Dari ramp itulah alias peran mengambil nilai, dan derivasi ringan seperti tint latar dihasilkan dengan fungsi color-mix() — fitur yang merupakan Baseline sejak 2023 dan dapat dipakai di seluruh browser utama. Dasar notasi warna sudah kita bahas pada Chapter Color Syntax ; chapter ini fokus pada strukturnya sebagai sistem.

Ramp 50-900: Satu Hue, Sembilan Tingkat #

Setiap ramp diberi nomor kecil untuk terang dan besar untuk gelap. Tingkatan 50-100 cocok untuk latar yang nyaris putih, 300-400 untuk aksen lembut dan ikon sekunder, 600-700 untuk aksi primer, dan 900 untuk teks kuat di atas latar terang. Palet demo kita memakai dua ramp — aksen biru dan netral abu — yang dideklarasikan sebagai primitive pada :root:

:root {
  /* Ramp aksen biru (cuplikan 50-900) */
  --biru-50: rgb(239, 246, 255);
  --biru-100: rgb(219, 234, 254);
  --biru-300: rgb(147, 197, 253);
  --biru-600: rgb(37, 99, 235);
  --biru-700: rgb(29, 78, 216);
  --biru-900: rgb(30, 58, 138);

  /* Ramp netral abu */
  --abu-50: rgb(248, 250, 252);
  --abu-200: rgb(226, 232, 240);
  --abu-700: rgb(51, 65, 85);
  --abu-900: rgb(15, 23, 42);

  /* Alias peran — membaca ramp, bukan nilai mentah */
  --aksi: var(--biru-600);
  --aksi-hover: var(--biru-700);
  --teks: var(--abu-900);
  --teks-samping: var(--abu-700);
  --garis: var(--abu-200);
  --latar: var(--abu-50);

  /* Derivasi color-mix() untuk tint */
  --lencana-latar: color-mix(in srgb, var(--biru-600) 25%, rgb(255, 255, 255));
  --lencana-garis: color-mix(in srgb, var(--biru-600) 50%, rgb(255, 255, 255));
}

Mari kita telaah keputusannya:

  1. Ramp disimpan sebagai primitive: angka 50-900 adalah konvensi yang sama dengan milik Tailwind dan sistem desain populer lain, sehingga anggota tim baru langsung menyalakannya tanpa penjelasan tambahan.
  2. Alias peran merujuk tingkatan: --aksi-hover tidak menciptakan warna baru, melainkan melangkah satu tingkat ke --biru-700. Perubahan status memakai ramp yang ada, bukan warna liar.
  3. color-mix() untuk derivasi: dua token terakhir menghasilkan tint — campuran 25% dan 50% --biru-600 dengan putih dalam ruang warna sRGB — untuk latar dan garis lencana.

Kapan Memakai Ramp, Kapan color-mix() #

Dua jalur derivasi ini saling melengkapi. Ramp adalah keputusan desain yang sudah matang: langkah hover, focus ring, dan teks di atas aksen sebaiknya memilih tingkatan yang sudah dikurasi agar kontrasnya terjaga — kita mengukurnya dengan alat pada Chapter Color Contrast . color-mix() adalah derivasi mekanis: membuat versi 25% dan 50% dari warna yang sama tanpa perlu mengkurasi tingkatan baru, sehingga ramp tetap ramping. Keduanya hidup berdampingan: ramp untuk peran penting, color-mix() untuk variasi sekunder yang tidak layak masuk katalog.

Demo: Swatch Ramp dan Lencana Derivasi #

Demo chapter ini menampilkan deretan swatch dari kedua ramp serta lencana yang latar dan garisnya berasal dari color-mix(). Hasil di Browser:

text
Swatch --biru-600 tampil rgb(37, 99, 235) dan swatch --biru-50
tampil rgb(239, 246, 255).
Lencana "Baru" berlatar hasil campuran 25% --biru-600 dengan putih:
background-color color(srgb 0.786275 0.847059 0.980392).
Garis aksen di bawah judul berlatar campuran 50%:
background-color color(srgb 0.572549 0.694118 0.960784).

Perhatikan dua baris terakhir: browser menserialisasi hasil color-mix() ke dalam ruang warna sRGB color(srgb ...) alih-alih rgb() — nilai computed seperti ini yang diperiksa harness melalui penanda data-expected. Nilai persentasenya mudah dihitung ulang: campuran 25% berarti 0,75 × 255 + 0,25 × tiap kanal --biru-600. Ketika tema gelap dibangun pada Chapter Dark Mode , alias peran inilah yang ditimpa — struktur ramp tidak berubah sama sekali.

Berkas Sumber

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

contoh-palet.css

Unduh berkas
css
:root {
  /* Ramp aksen biru (cuplikan 50-900) */
  --biru-50: rgb(239, 246, 255);
  --biru-100: rgb(219, 234, 254);
  --biru-300: rgb(147, 197, 253);
  --biru-600: rgb(37, 99, 235);
  --biru-700: rgb(29, 78, 216);
  --biru-900: rgb(30, 58, 138);

  /* Ramp netral abu */
  --abu-50: rgb(248, 250, 252);
  --abu-200: rgb(226, 232, 240);
  --abu-700: rgb(51, 65, 85);
  --abu-900: rgb(15, 23, 42);

  /* Alias peran — membaca ramp, bukan nilai mentah */
  --aksi: var(--biru-600);
  --aksi-hover: var(--biru-700);
  --teks: var(--abu-900);
  --teks-samping: var(--abu-700);
  --garis: var(--abu-200);
  --latar: var(--abu-50);

  /* Derivasi color-mix() untuk tint */
  --lencana-latar: color-mix(in srgb, var(--biru-600) 25%, rgb(255, 255, 255));
  --lencana-garis: color-mix(in srgb, var(--biru-600) 50%, rgb(255, 255, 255));
}

.swatch {
  width: 72px;
  height: 48px;
  border: 1px solid var(--abu-200);
  border-radius: 6px;
}

.swatch-biru-600 { background-color: var(--biru-600); }
.swatch-biru-50 { background-color: var(--biru-50); }

.lencana {
  display: inline-block;
  background-color: var(--lencana-latar);
  border: 1px solid var(--lencana-garis);
  color: var(--biru-700);
  border-radius: 999px;
  padding: 4px 12px;
  font-size: 12px;
  font-weight: 600;
}

.garis-aksen {
  height: 4px;
  border: 0;
  background-color: var(--lencana-garis);
  border-radius: 2px;
}