OKLCH dan Warna CSS Modern — Mengapa Palet Anda Terlihat Salah di Beberapa Browser
RGB dan HSL dibangun untuk monitor CRT. Kenapa OKLCH memperbaiki ketidakseragaman persepsi, bagaimana color-mix() mengubah penggabungan gradien, dan apa yang dibuka oleh sintaks warna relatif tanpa preprocessor.
Anda memilih biru untuk tombol utama Anda. Tampaknya benar di browser Anda. Anda membuka staging di MacBook Pro yang lebih baru dan tampaknya... cukup baik — hanya sedikit datar. Desainer mengirim tangkapan layar dari iPhone mereka dan tombol yang sama tampak jauh lebih hidup. Kode heksa sama. Tampilan berbeda.
Itu adalah celah P3. Dan sebenarnya ini adalah bagian paling tidak menarik dari alasan model warna CSS yang Anda gunakan gagal menguntungkan Anda. Masalah utama adalah matematika di balik HSL.
Tingkat maksimum sRGB
Setiap warna heksa dan rgb() nilai yang pernah Anda tulis berada dalam ruang warna sRGB — standar yang dibangun pada tahun 1996 untuk monitor CRT. Ruang warna sRGB mencakup sekitar 35% dari warna yang terlihat oleh mata manusia. Ruang warna P3, yang digunakan oleh setiap iPhone sejak 2017 dan sebagian besar MacBook sejak 2016, mencakup sekitar 45%.
Ketika Anda menulis #3b82f6, warna tersebut dibatasi pada sRGB. Di tampilan P3, browser secara teoritis dapat menampilkan biru yang lebih terang — tetapi CSS Anda tidak meminta itu. Anda meninggalkan kemampuan tampilan yang tersedia secara default.
Untuk mengakses warna P3 secara langsung Anda akan menggunakan color(display-p3 0.2 0.4 0.9). Ini bekerja. Tapi ini bukan alasan mengapa OKLCH penting. Kekalahan utama terletak pada asumsi inti dari HSL.
Luminositas HSL adalah kebohongan
HSL adalah perbaikan nyata dibandingkan heksa. Hue, Saturation, Lightness — secara konseptual masuk akal, dapat diedit oleh manusia. Masalahnya: "L" tidak berarti apa yang Anda pikirkan.
Letakkan kuning di hsl(60, 100%, 50%) dan biru di hsl(240, 100%, 50%) berdampingan. Keduanya berada pada tingkat persis 50% luminositas.
.yellow { background: hsl(60, 100%, 50%); }
.blue { background: hsl(240, 100%, 50%); }
Kuning terlihat hampir putih. Biru terlihat gelap sedang. Keduanya tidak sama dalam tingkat kecerahan yang dirasakan. Ini adalah ketidakseragaman persepsi HSL — sumbu L tidak mencerminkan cara penglihatan manusia memproses kecerahan.
Ini menciptakan masalah pemeliharaan nyata saat membangun skala warna. Jika Anda menghasilkan skala 9 langkah dengan mengatur nilai L dalam HSL, warna kuning dan sian terlihat terlalu terang, sementara biru dan ungu terlihat kabur. Anda akhirnya harus menyesuaikan nilai secara manual, yang menghancurkan seluruh tujuan memiliki pendekatan sistematis.
OKLCH: dirancang untuk persepsi
OKLCH dirancang oleh Björn Ottosson pada tahun 2020. Ini berdasarkan CIELAB (ruang warna persepsi dari tahun 1970-an) tetapi memperbaiki pergeseran warna yang dikenal — terutama masalah ungu/biru di mana peningkatan chroma akan secara visual mengubah warna yang dilihat.
Tiga saluran:
- L (Luminositas) — dari 0 hingga 1, secara persepsi seragam. L 0.5 pada kuning terlihat sama kecerahannya dengan L 0.5 pada biru. Sebenarnya.
- C (Chroma) — dimulai dari 0 (warna abu-abu), meningkat hingga sekitar 0.3–0.4 untuk warna yang sangat terang. Tidak ada batas maksimum — batas atas bervariasi tergantung warna dan ruang warna target.
- H (Hue) — dari 0 hingga 360 derajat, secara kasar sebanding dengan hue di HSL.
Berikut ini adalah warna biru Tailwind-500 dalam sistem kedua:
/* sRGB hex */
background: #3b82f6;
/* OKLCH equivalent — same color, different notation */
background: oklch(0.623 0.214 259.1);
/* Push chroma past sRGB — more vivid blue on P3 displays, clips gracefully on sRGB */
background: oklch(0.623 0.27 259.1);
Nilai terakhir tersebut berada di luar batas gamut sRGB. Browser pada tampilan P3 menampilkan versi yang lebih hidup; browser yang lebih tua memotong ke versi terdekat dalam sRGB. Peningkatan bertahap dengan usaha nol.
color-mix() dan mengapa ruang warna mengubah blending
color-mix() diluncurkan di Chrome 111, Firefox 113, dan Safari 16.2. Ini mencampur dua warna dengan rasio — cukup sederhana. Tapi ruang warna yang Anda tentukan secara signifikan mengubah hasilnya.
/* Mixes through sRGB — midpoint is a washed-out brown-grey */
background: color-mix(in srgb, oklch(0.7 0.2 30), oklch(0.7 0.2 270));
/* Mixes through the OKLCH color wheel — midpoint is a vivid purple */
background: color-mix(in oklch, oklch(0.7 0.2 30), oklch(0.7 0.2 270));
Ketika Anda mencampur oranye dan biru dalam sRGB, Anda mengambil rata-rata nilai saluran. Titik tengah melewati warna abu-abu yang terdekat. Dalam OKLCH, Anda melakukan interpolasi sepanjang roda warna — Anda tiba di warna ungu yang hidup. Mana yang benar tergantung pada niat, tetapi untuk transisi UI, gradien, dan keadaan hover, interpolasi OKLCH hampir selalu yang Anda inginkan.
Penerapan praktis: menghasilkan keadaan tidak aktif tanpa harus mengkodekan nilai heksa kedua.
.button--disabled {
background: color-mix(in oklch, var(--color-primary) 40%, white);
cursor: not-allowed;
}
Sintaksis warna relatif
Sintaksis warna relatif (Chrome 119+, Firefox 128+, Safari 16.4+) memungkinkan Anda menghasilkan warna baru dengan memodifikasi saluran individu dari warna yang ada:
:root {
--brand: oklch(0.623 0.214 259.1);
}
.button:hover {
/* Lighten by 8% lightness units */
background: oklch(from var(--brand) calc(l + 0.08) c h);
}
.button:active {
/* Darken and reduce chroma slightly */
background: oklch(from var(--brand) calc(l - 0.08) calc(c - 0.02) h);
}
.button--muted {
/* Drop chroma to near-zero: perceptual grey at the same lightness */
background: oklch(from var(--brand) l 0.03 h);
}
Ini menggantikan Sass’s lighten(), darken()dan desaturate() dengan CSS bawaan — tidak perlu preprocessor, tidak perlu langkah pembangunan, tidak perlu nilai heksa yang harus disinkronkan. Dan karena Anda berada di OKLCH, "mengangkat" sebenarnya terlihat lebih terang di setiap warna dalam palet Anda, bukan hanya beberapa dari mereka.
Satu keterbatasan nyata: kendala saluran kompleks (seperti membatasi chroma agar tetap dalam ruang warna) membutuhkan rantai calc() yang menjadi rumit cepat. Untuk perubahan kecerahan dan chroma sederhana, sintaksis ini bersih. Untuk hal yang lebih canggih, perhitungan nilai saat pembangunan dan generasi properti CSS lebih mudah dipertahankan.
Dukungan browser pada tahun 2026
| Fitur | krom | Firefox | Taman Safari |
|---|---|---|---|
oklch() | 111+ | 113+ | 15.4+ |
color-mix() | 111+ | 113+ | 16.2+ |
| Sintaksis warna relatif | 119+ | 128+ | 16.4+ |
color(display-p3) | 111+ | 113+ | 10+ |
Dukungan global untuk oklch() melebihi 90% pada pertengahan tahun 2026. Pihak yang masih menahan diri adalah browser berbasis Chromium lama dan semua versi Firefox di bawah 113. Jika ini merupakan bagian dari pengguna Anda, dua baris fallback cukup Anda butuhkan:
.button {
background: #3b82f6; /* sRGB fallback */
}
@supports (background: oklch(0 0 0)) {
.button {
background: oklch(0.623 0.214 259.1);
}
}
Dalam praktiknya: jika analitik Anda memastikan Chrome 111+, Firefox 113+, dan Safari 15.4+, Anda dapat mengabaikan fallback sepenuhnya. Wrapper @supports adalah untuk keamanan dalam alat internal di mana Anda tidak mengontrol versi browser.
Konversi palet Anda
Titik gesekan dengan adopsi OKLCH adalah perpindahan dari nilai heksa saat ini ke koordinat OKLCH dan memahami arti saluran untuk setiap warna. Pengubah Ruang Warna Terpadu mengelola konversi dalam kedua arah — salin nilai heksa atau HSL, dapatkan nilai OKLCH, lalu mulai menyesuaikan L dan C dari titik referensi nyata. Ini mendukung HSL, RGB, Lab, LCH, HSV, dan OKLCH dalam satu tempat, yang berguna ketika Anda bekerja dari file Figma yang memberikan nilai heksa dan perlu menempatkan nilai OKLCH yang dapat dipahami.
Cara benar-benar pindah
Anda tidak perlu menulis semuanya sekaligus. Urutan praktis:
- Mulai dengan warna interaktif — token utama, sekunder, dan destruktif Anda. Ini adalah yang sudah Anda hasilkan variasi hover, aktif, dan tidak aktif. OKLCH + sintaksis warna relatif menggantikan logika tersebut secara langsung dengan CSS bawaan.
- Biarkan warna statis tetap dalam heksa untuk saat ini — teks, latar belakang, batas. Mereka tidak dimanipulasi secara programatis, jadi belum ada manfaat untuk mengonversinya.
- Bangun sistem baru dari awal dalam OKLCH — di sini keunggulan persepsi menjadi struktural. Skala netral langkah 500 akan benar-benar berada di tengah secara visual, dan warna terang akan konsisten di semua warna tanpa penyesuaian manual.
Tujuan bukan OKLCH demi kepentingan sendiri. Ini adalah sistem warna di mana matematikanya sesuai dengan apa yang dilihat mata Anda — sehingga Anda berhenti menyesuaikan secara manual setiap kali Anda butuh biru yang sedikit lebih terang.
Instal Ekstensi Kami
Tambahkan alat IO ke browser favorit Anda untuk akses instan dan pencarian lebih cepat
恵 Papan Skor Telah Tiba!
Papan Skor adalah cara yang menyenangkan untuk melacak permainan Anda, semua data disimpan di browser Anda. Lebih banyak fitur akan segera hadir!
Alat Wajib Coba
Lihat semua Pendatang baru
Lihat semuaMemperbarui: Kita alat terbaru ditambahkan pada 15 Juni 2026
