Tema warna dengan fitur CSS Dasar

David A. Herron
David A. Herron

Dipublikasikan: 11 Desember 2025

Jadi, Anda memiliki situs yang ingin dibuat atau didesain ulang. Mungkin Anda sudah memikirkan beberapa warna inti, dan Anda sedang memikirkan cara menerapkan tema dengan cepat berdasarkan warna-warna tersebut.

Anda akan memerlukan warna primer, tetapi juga warna untuk tindakan, status pengarahan kursor, error, dan warna untuk kebutuhan antarmuka pengguna lainnya. Lalu, bagaimana dengan opsi mode terang dan gelap? Tiba-tiba ada banyak warna yang Anda butuhkan, dan hal ini bisa terasa membingungkan.

Kabar baiknya adalah bahwa dalam hal membuat palet yang relatif terhadap token warna yang menentukan situs Anda dan beralih di antara mode warna, fitur Baseline dapat melakukan banyak pekerjaan berat untuk Anda. Anda dapat mempelajari beberapa teknik ini dalam demo unggulan, yaitu playlist bertema warna di situs fiktif Baseline Radio.

Membangun dasar dengan warna relatif

Jika Anda memiliki ide untuk warna primer tema Anda, dengan beberapa teori warna dasar dan sintaksis warna relatif CSS, Anda dapat dengan cepat mulai membuat palet warna untuk digunakan dalam tema Anda.

Misalnya, warna dasar Anda adalah warna hijau kebiruan, yang dapat Anda tentukan terlebih dahulu dalam format warna pilihan Anda. Kemudian, Anda dapat menggunakan fungsi warna apa pun untuk membuat warna baru yang relatif terhadap warna dasar:

html {
  --base-color: oklch(43.7% 0.075 224);
}

Properti kustom --base-color dibuat menggunakan fungsi warna oklch(). OkLCh adalah bentuk silindris dari ruang warna Oklab, dan menentukan nilai untuk tiga saluran: L (kecerahan), C (kroma), H (warna), ditambah saluran alfa opsional untuk mengontrol transparansi.

OkLCh adalah format yang baik untuk jenis manipulasi warna ini, karena dirancang untuk memberikan keseragaman persepsi. Misalnya, jika Anda hanya menyesuaikan hue warna, warna yang dihasilkan akan memiliki kecerahan dan kroma yang serupa dengan warna aslinya. Hal ini sangat berguna untuk menghindari masalah kontras yang tidak terduga.

Dengan mempertahankan kecerahan dan kroma yang sama dari --base-color, Anda dapat menyesuaikan warna sebesar 120 derajat di kedua arah untuk palet triadik.

html {
  /* ... */
  --triadic-color-primary: oklch(from var(--base-color) l c calc(h + 120));
  --triadic-color-secondary: oklch(from var(--base-color) l c calc(h - 120));
}

Seperti yang ditunjukkan di sini, sintaksis warna relatif menggunakan fungsi warna yang mereferensikan warna asal (--base-color dalam contoh ini) dengan kata kunci from, dan menyesuaikan masing-masing saluran ruang warna berdasarkan warna output yang dipilih, yang dalam hal ini juga akan menjadi OkLCh.

Output yang dihasilkan akan memberi Anda warna merah muda gelap untuk --accent-color, dan warna emas untuk --highlight-color, keduanya dengan kecerahan dan kroma yang sama seperti --base-color asli.

html {
  /* ... */
  --accent-color: var(--triadic-color-primary);
  --highlight-color: var(--triadic-color-secondary);
}

  html {
    /* Input color in the rgb color space*/
    --base-color: teal;

     /* Output color in oklch. Computes to oklch(0.543123 0.0927099 314.769) */
     --triadic-color-primary: oklch(from var(--base-color) l c calc(h + 120));
  }

Warna pelengkap akan menambahkan 180 derajat ke sudut warna.

html {
  /* ... */
  --complement-color: oklch(from var(--base-color) l c calc(h + 180));
  --border-highlight: var(--complement-color);
}

Untuk status arahkan kursor di UI, Anda mungkin ingin menghasilkan versi warna tertentu yang lebih terang. Hal ini berarti meningkatkan nilai saluran kecerahan. Untuk status aktif, Anda mungkin ingin menambahkan transparansi dengan menyesuaikan saluran alfa, atau menggelapkannya dengan mengurangi nilai saluran kecerahan.

html {
  /* Darken the --base-color by 15% */
  --base-color-darkened: oklch(from var(--base-color) calc(l * 0.85) c h);
  /* Assign this color a meaningful variable name */
  --action-color: var(--base-color-darkened);
  /* Lighten the --action-color by 15% */
  --action-color-light: oklch(from var(--action-color) calc(l * 1.15) c h);
  /* Darken the --action-color by 10% */
  --action-color-dark: oklch(from var(--action-color) calc(l * 0.9) c h);
}

Di sini, kita mendapatkan --action-color dari --base-color, dan menggunakannya untuk tombol dan link. --action-color memiliki dua varian—lebih terang dan lebih gelap—yang akan tetap berlaku meskipun --action-color diubah agar relatif terhadap warna lain yang berbeda dari --base-color.

Anda dapat menyesuaikan saluran menggunakan fungsi matematika seperti calc() atau mengganti saluran sepenuhnya dengan nilai baru. Channel yang tidak berubah diwakili oleh hurufnya masing-masing (misalnya, l untuk nilai kecerahan yang tidak berubah).

Campur warna dengan color-mix()

Untuk varian warna lainnya, Anda dapat menggunakan pendekatan serupa dan menyesuaikan saluran lain dari properti kustom --base-color. Atau, gunakan color-mix() untuk menambahkan sentuhan warna dasar ke aspek lain dalam desain Anda.

--border-color adalah campuran warna dasar dan warna bernama grey, yang diinterpolasi dalam ruang warna oklab. Jika digunakan sebagai metode interpolasi warna, metode ini memberikan hasil yang seragam secara perseptual.

html {
  --base-mix-grey-50: color-mix(in oklab, var(--base-color), grey);
  --border-color: var(--base-mix-grey-50);
}

Secara default, ini akan menjadi 50% dari setiap warna, tetapi Anda dapat membuat salah satu warna lebih atau kurang dominan dengan menyesuaikan bobot persentasenya.

html {
  --background-mix-base-80: color-mix(in oklab,
    var(--background-color) 80%,
    var(--base-color));
  --surface-light: var(--background-mix-base-80);
}

Alternatif untuk menambahkan lebih banyak warna ke elemen adalah dengan menyesuaikan saluran chroma menggunakan sintaksis warna relatif. Batas input teks dalam formulir kontak memiliki batas yang sedikit lebih berwarna saat dalam fokus.

[data-input*="text"] {
  --focus-ring: transparent;
  /* ... */
  &:focus {
    --focus-ring: oklch(from var(--border-color) l calc(c + 0.1) h);
  }
}

Memilih untuk menggunakan mode terang dan gelap

Setelah memiliki sekumpulan warna untuk digunakan, Anda akan menginginkan cara yang efisien untuk menerapkan warna yang berbeda untuk mode terang dan gelap.

Mendukung tema terang dan gelap dengan properti color-scheme

Anda dapat langsung memberi tahu browser bahwa situs Anda dapat dilihat dalam mode "terang", "gelap", atau keduanya dengan properti color-scheme. Properti ini memberi tahu browser dalam skema warna mana elemen dapat dirender dengan nyaman.

 html {
   color-scheme: light dark;
}

Menetapkan color-scheme: light dark pada elemen semu :root atau elemen html:

  • Memberi tahu browser bahwa halaman Anda mendukung tampilan dalam mode terang atau gelap.
  • Mengubah warna default antarmuka pengguna browser agar sesuai dengan setelan sistem operasi masing-masing.

Untuk memberi tahu agen pengguna lebih awal bahwa halaman Anda mendukung mode terang dan gelap, Anda juga dapat menandakan dukungan untuk pengalihan skema warna dengan menambahkan elemen <meta> di <head> dokumen.

<head>
  <!-- ... -->
   <meta name="color-scheme" content="light dark">
</head>

Menetapkan varian "terang" dan "gelap" dengan fungsi light-dark()

Sebagai penulis, Anda mungkin terbiasa menyetel warna halaman dengan kueri prefers-color-scheme @media.

@media (prefers-color-scheme: light) {
  html {
    --background-color: oklch(95.5% 0 162);
    --text-color: black;
  }
}

@media (prefers-color-scheme: dark) {
  html {
    --background-color: oklch(22.635% 0.01351 291.83);
    --text-color: white;
  }
}

Hal ini berfungsi baik untuk warna dan gaya yang dikontrol oleh penulis, tetapi seperti yang disebutkan di bagian sebelumnya, Anda tetap memerlukan color-scheme untuk memperbarui warna UI browser.

Mengubah warna halaman dengan kueri prefers-color-scheme juga berarti beberapa duplikasi kode karena Anda harus menentukan warna untuk setiap mode secara terpisah.

Namun, dengan color-scheme yang ditetapkan di seluruh halaman (atau elemen tertentu), Anda dapat menggunakan fungsi light-dark() untuk menetapkan warna untuk setiap mode dalam satu baris kode.

Fungsi ini menerima dua warna. Yang pertama digunakan saat skema warna disetel ke "terang", dan yang kedua saat skema warna disetel ke "gelap".

html {
  color-scheme: light dark;
  /* Color custom property values for both light and dark modes */
  --base-color: light-dark(oklch(43.7% 0.075 224), oklch(89.2% 0.069 224));
  --background-color: light-dark(oklch(95.5% 0 162), oklch(22.635% 0.01351 291.83));
  --accent-color: oklch(from var(--base-color) l c calc(h + 120));
  --active-color: light-dark(var(--action-color-light), var(--action-color-dark));
  /* ... */
}

Seperti properti kustom lainnya, setelan light-dark() untuk warna dapat ditetapkan secara global atau dalam komponen tertentu, lalu digunakan di tempat lain sesuai kebutuhan.

/* custom property usage */
body {
  background-color: var(--background-color);
  /* ... */
}

:any-link {
  /* ... */
  text-decoration-color: var(--accent-color);
}

Memberi pengguna kontrol dengan pengalih tema bawaan

Memiliki tema yang beradaptasi dengan preferensi warna sistem atau browser default pengguna memang bagus, tetapi Anda dapat melangkah lebih jauh dan memberi penonton situs Anda kemampuan untuk mengganti preferensi warna default ini.

Jika Anda membuat tombol tema yang memperbarui atribut data-scheme pada elemen <html>, Anda dapat menggunakan atribut yang sama untuk mengubah color-scheme dengan CSS.

html {
  color-scheme: light dark;

  &[data-scheme="light"] {
    color-scheme: light;
  }

  &[data-scheme="dark"] {
    color-scheme: dark;
  }

  &[data-scheme="green"] {
      --base-color-light: oklch(48.052% 0.11875 151.945);
      --base-color-dark: oklch(92.124% 0.13356 151.558);
      color-scheme: light dark;
   }
}

data-scheme="light" dan data-scheme="dark" menampilkan halaman hanya dalam mode warna masing-masing. data-scheme="green" dapat dilihat dalam mode apa pun dan juga mengubah --base-color menjadi warna hijau, yang memberi Anda palet yang benar-benar baru karena sebagian besar warna lainnya didasarkan pada --base-color.

Mendaftarkan properti kustom dengan @property

Sejauh ini, warna dalam demo telah ditetapkan sebagai properti kustom standar. Anda juga dapat mendaftarkan properti dengan aturan @property untuk memanfaatkan manfaat yang disertakan dengan pemeriksaan jenis.

Karena --base-color digunakan sebagai dasar dari begitu banyak warna lain dalam antarmuka, sebaiknya pastikan --base-color selalu berupa warna dan memiliki nilai penggantian.

@property --base-color-light {
  syntax: '<color>';
  inherits: false;
  initial-value: oklch(43.7% 0.075 224);
}

@property --base-color-dark {
  syntax: '<color>';
  inherits: false;
  initial-value: oklch(89.2% 0.069 224);
}

html {
  --base-color: light-dark(var(--base-color-light), var(--base-color-dark));
}

Dengan cara ini, jika --base-color tidak sengaja diubah menjadi nilai yang tidak valid, --base-color akan selalu kembali ke initial-value yang ditetapkan dengan aturan @property.

Mendaftarkan properti tertentu dengan cara ini juga memungkinkan warna dianimasikan dengan lancar dalam linear-gradient().

.main-heading {
  background: linear-gradient(in oklch 90deg, var(--text-color) 50%, oklch(from var(--base-color) l c var(--header-hue)));
  background-clip: text;
  color: transparent;
  animation: header-hue-switch 5s ease-in-out infinite alternate;
}

.main-heading memiliki latar belakang linear-gradient() yang ditampilkan melalui teks transparan dengan properti background-clip.

Sebagian teks menampilkan hue yang, menggunakan sintaksis warna relatif, dianimasikan dari nilai saluran 26.67 ke 277:

@keyframes header-hue-switch {
  from {
    --header-hue: 26.67;
  }

  to {
    --header-hue: 277;
  }
}

Dengan properti kustom --header-hue yang terdaftar, animasi ini dapat terjadi dengan lancar karena browser mengetahui bahwa properti kustom ini adalah angka.

@property --header-hue {
  syntax: '<number>';
  inherits: false;
  initial-value: 100;
}

Dengan properti kustom yang tidak terdaftar, browser tidak akan mengetahui jenis data --header-hue, sehingga transisi ke angka akan menjadi animasi diskrit, yang akan melompat di antara status tanpa interpolasi bertahap.

Rangkuman

Alat Dasar baru dapat membantu Anda membuat palet warna yang dapat disesuaikan dengan cepat dan menjadikan proses pembuatan variabel warna lebih efisien. Namun, Anda tetap harus memilih sendiri opsi dan kombinasi warna yang tak ada habisnya.

Membuat palet secara dinamis seperti ini memberi Anda fleksibilitas. Jika perlu mengubah warna dasar untuk branding, Anda cukup memperbarui --base-color, dan tema lainnya akan mengikuti dari sana. Atau, jika Anda menambahkan kemampuan pemutaran musik, Anda dapat memutuskan bahwa Anda ingin mengubah warna dasar secara dinamis agar sesuai dengan lagu yang sedang diputar.

Kredit

Logika pengalih tema diadaptasi dari Komponen pengalih tema Adam Argyle.