- Dengan menggunakan fungsi contrast-color(), browser secara otomatis memilih warna teks hitam atau putih yang sesuai untuk berbagai warna latar seperti tombol
- Bahkan pada proyek berskala besar, keterbacaan teks tetap terjaga dengan lebih mudah dan efisiensi pemeliharaan meningkat
- Saat ini di Safari Technology Preview, digunakan algoritme resmi WCAG 2, tetapi ini dapat berbeda dari persepsi manusia yang sebenarnya
- Pembahasan penerapan algoritme APCA generasi berikutnya sedang berlangsung dalam proses pengembangan WCAG 3, dan menjanjikan evaluasi kontras luminans yang lebih baik
- Selain kontras hitam-putih sederhana, ke depannya diperkirakan akan ditambahkan berbagai opsi warna dan fitur peningkatan aksesibilitas
Gambaran umum dan latar belakang hadirnya contrast-color()
- Dalam desain yang menggunakan berbagai warna latar pada banyak tombol atau komponen antarmuka, keterbacaan warna font (warna teks) sangat penting
- Sebelumnya, pengembang harus mencocokkan warna latar dan warna teks satu per satu secara manual, tetapi pada proyek besar kompleksitas pengelolaan dan risiko kesalahan menjadi tinggi
- Dengan fungsi CSS contrast-color(), pengembang cukup menentukan warna latar, lalu browser otomatis memilih warna teks hitam atau putih dengan kontras yang lebih tinggi
- Dengan cara ini, efisiensi pemeliharaan dan pekerjaan desain meningkat secara signifikan
- Penggunaannya sederhana, cukup dideklarasikan seperti
color: contrast-color(warna);
Contoh penggunaan contrast-color()
- Tetapkan warna yang diinginkan pada variabel warna latar tombol, lalu warna teks akan otomatis dipilih menjadi salah satu dari hitam atau putih yang kontras melalui
contrast-color()
- Karena hanya perlu mengelola satu warna sekaligus, maintenance menjadi lebih mudah saat kebijakan desain berubah atau ketika mendukung mode gelap/terang
button {
background-color: var(--button-color);
color: contrast-color(var(--button-color));
}
- Dengan memanfaatkan Relative Color Syntax, warna latar dan warna teks pada status hover juga dapat dikelola secara konsisten
Pertimbangan aksesibilitas dan penjelasan algoritme
- Penggunaan
contrast-color() tidak otomatis menyelesaikan semua masalah aksesibilitas (Accessibility)
- Pada warna latar dengan tingkat kecerahan menengah tertentu, baik hitam maupun putih bisa saja sama-sama tidak memenuhi standar yang dibutuhkan
- Algoritme WCAG 2 yang saat ini digunakan di Safari Technology Preview adalah standar resmi aksesibilitas web
- Algoritme ini memilih berdasarkan rasio kontras, tetapi kadang menghasilkan hasil yang tidak selaras dengan kontras luminans yang benar-benar terlihat oleh mata
- Sebagai contoh, pada latar biru #317CFF, secara mekanis hitam dihitung memiliki kontras lebih tinggi, tetapi dalam praktiknya putih lebih mudah dibaca
- Menanggapi kritik dan kebutuhan perbaikan tersebut, pembahasan penerapan APCA (Accessible Perceptual Contrast Algorithm) yang lebih unggul sedang berlangsung dalam standar aksesibilitas generasi berikutnya (WCAG 3)
- APCA menghitung kontras warna dengan merefleksikan karakteristik persepsi manusia, sehingga lebih mampu menjamin keterbacaan nyata
Memberikan kontras yang memadai di lingkungan nyata
- Dengan memanfaatkan media query CSS
@media (prefers-contrast: more), kita dapat menerapkan gaya kontras tinggi tambahan sesuai preferensi aksesibilitas pengguna
@media (prefers-contrast: more) {
/* Definisikan gaya dengan kontras lebih tinggi */
}
- Sebagai contoh, jika warna inti merek adalah hijau terang seperti #2DAD4E, meskipun di masa depan
contrast-color() memilih putih, untuk teks kecil kontrasnya mungkin tetap belum cukup
- Dengan menerapkan algoritme APCA, kita dapat merujuk secara rinci pada standar kontras minimum yang dibutuhkan berdasarkan ukuran dan ketebalan font, sehingga membantu pengambilan keputusan desain dalam praktik
- Dalam praktiknya, untuk teks 24px dengan ketebalan 400, penggunaan putih cocok, tetapi untuk FONT yang lebih tipis atau teks yang lebih kecil, disarankan menggunakan warna latar yang lebih gelap
- Tim desain dapat dengan mudah mengelola palet warna dengan variabel untuk tiap kondisi dengan mempertimbangkan light/dark mode, preferensi prefers-contrast, dan sebagainya
--button-color: #2DAD4E;
@media (prefers-contrast: more) {
@media (prefers-color-scheme: light) {
--button-color: #419543;
}
@media (prefers-color-scheme: dark) {
--button-color: #77CA8B;
}
}
button {
background-color: var(--button-color);
color: contrast-color(var(--button-color));
font-size: 1.5rem;
font-weight: 500;
}
- Intinya, berkat
contrast-color(), kita cukup mengelola warna dengan berfokus pada warna latar, sementara pasangan kontras warna teks akan dibuat otomatis oleh browser
Melampaui hitam dan putih
contrast-color() saat ini hanya memilih dari dua opsi, hitam atau putih, tetapi versi awalnya juga dapat memilih dari beberapa warna
- CSS Working Group untuk sementara memprioritaskan versi sederhana (hanya memilih hitam/putih) demi kompatibilitas dengan perubahan algoritme di masa depan, dan ke depannya juga merencanakan perluasan seperti opsi warna kustom dan penentuan standar kontras minimum yang diinginkan
- Untuk kebutuhan sederhana, fungsi ini sudah sangat berguna
- Fungsi ini dapat diterapkan secara luas bukan hanya pada warna latar, tetapi juga border dan elemen visual lainnya
Kesimpulan dan informasi referensi
- Setelah standar aksesibilitas generasi berikutnya diadopsi,
contrast-color() akan mengganti algoritmenya untuk mendukung pemilihan kontras otomatis yang lebih baik
- Sampai saat itu, fungsi ini sangat berguna terutama ketika warna latar utama jelas terang atau gelap
- Fungsi ini juga dapat diterapkan secara luas pada berbagai elemen UI selain teks
- Sebaiknya tetap mengikuti perkembangan algoritme aksesibilitas modern seperti APCA (Accessible Perceptual Contrast Algorithm)
Referensi
- Dokumentasi resmi APCA dan APCA Contrast Calculator dapat digunakan untuk memeriksa berbagai contoh dan standar evaluasi
- Diskusi standardisasi terkait fungsi contrast-color di CSSWG masih berlangsung
- Berbagi pendapat dan berpartisipasi dalam feedback dimungkinkan melalui WebKit atau komunitas terkait
1 komentar
Komentar Hacker News
Saya sedang mengembangkan alat untuk membuat palet agar pasangan warna memiliki rasio kontras WCAG/APCA yang sederhana dan dapat diprediksi sejak tahap desain. Situs https://www.inclusivecolors.com/ menyediakan lebih banyak fitur di desktop. Salah satu caranya adalah membuat contoh warna bertingkat dari 100 (warna terang) hingga 900 (warna gelap), lalu menyesuaikan kecerahan agar misalnya warna tingkat 700 memiliki kontras yang jelas dengan tingkat 100, dan 800 dengan 200. Dengan begitu, kita bisa tahu bahwa kombinasi seperti red-700 vs gray-100 atau green-800 vs yellow-200 pasti memberi kontras yang jelas tanpa perlu memeriksa luminans. Di menu Contrast, Anda juga bisa mengeksplorasi seberapa ketat algoritma APCA dibandingkan WCAG, terutama pada teks gelap di atas latar terang. Itulah sebabnya WCAG tidak cocok dipakai untuk tema gelap. Di menu Examples, jika melihat contoh palet Tailwind dan IBM Carbon, tiap tingkat berubah secara nonlinier dalam saturasi dan hue, jadi memilih kontras optimal antara hitam/putih memang mudah, tetapi untuk palet yang penting bagi branding, ini masalah yang jauh lebih kompleks dan warna tidak bisa dihasilkan hanya dengan menyesuaikan kecerahan.
Ada cara melakukan sesuatu yang mirip dengan memakai lch
Sumber: https://til.jakelazaroff.com/css/…
LCH juga keren, tapi OKLCH lebih unggul. https://evilmartians.com/chronicles/oklch-in-css-why-quit-rgb-hsl/… Artikel ini benar-benar mengubah cara pikir saya. Alat yang luar biasa. Anehnya, tidak satu pun teman desainer saya yang tahu tentang OKLCH. Pendekatan ini menyelesaikan banyak masalah.
Ini pertama kalinya saya melihat fungsi CSS yang bisa menerima parameter lewat callback seperti ini. Konsep yang sangat menarik. Saya penasaran apakah ada fungsi lain selain lch dengan gaya seperti ini.
Ada tulisan bagus dari Lea Verou tentang solusi serupa. https://lea.verou.me/blog/2024/contrast-color/
Artikel ini adalah ringkasan yang sangat baik tentang kelebihan dan kekurangan pemilihan kontras otomatis. Jika Anda membuat situs yang sederhana, cara ini mudah dan sederhana untuk memberi kontras yang benar.
Tetapi jika membutuhkan kepatuhan WCAG dalam skala besar, sebaiknya dihindari dan Anda benar-benar memerlukan lapisan token format berbasis semantik. Token semantik mempercepat pengembangan, dan bisa menjamin kontras yang secara visual lebih baik daripada sekadar beralih antara hitam/putih. Hal baik dari lapisan token semantik adalah pembuatan tema menjadi sangat mudah, sehingga tema terang/gelap bisa dibuat nyaris tanpa biaya tambahan. Jika warna merek Anda tidak lolos WCAG2, Anda bisa membuat tema terpisah untuk WCAG2/APCA agar tetap patuh sambil memberi kontras yang lebih baik.
Saya menangani alur variables/tokens di Figma, dan juga terlibat dalam implementasi mode gelap di Figma dan Atlassian. Kalau ada pertanyaan tentang token, tema, atau warna aksesibilitas, silakan tanya.
Saya penasaran apa tepatnya yang dimaksud dengan token semantik. Karena fitur seperti ini, saya memakai CSS-in-JS di proyek besar yang saya kerjakan untuk kalkulasi relatif warna dan warna kontras. Saya berharap teknik seperti ini segera diadopsi luas.
Dua pertiga bagian terakhir terlalu bertele-tele sehingga terkesan sok ilmiah. Di situs/aplikasi perusahaan, berbahaya bergantung pada fungsi seperti ini karena warna hasilnya tidak bisa diprediksi. Hasil warnanya bisa berubah kalau WebKit memperbaiki bug.
Saya masih sulit setuju bahwa warna kontras yang ditentukan berdasarkan penilaian vendor browser itu selalu benar atau dapat diprediksi. Saya penasaran apakah akan ada standar deterministik yang membuat semua browser menghasilkan hal yang sama. Fungsi ini terasa lebih seperti alat pendukung tahap desain untuk tim UX.
Menurut artikelnya, standar tersebut menyebutkan metode perhitungannya dengan jelas
Kata "memilih" terdengar ambigu. Sebenarnya algoritma yang menghasilkan warnanya
Jika mengabaikan kesalahan atau bagian yang membingungkan di rumus contoh APCA pada tautan itu, ia bekerja 100% akurat. Agar benar-benar konsisten, saat dua warna kandidat (yang lebih terang dan yang lebih gelap) sama-sama diperbolehkan, Anda bisa memakai kecerahan latar (L*) sebagai patokan, misalnya jika L* 60 atau lebih maka pilih yang terang. Dengan begitu akan 100% konsisten.
Kalau sulit memastikan di proyek besar agar tombol tidak berubah menjadi warna yang tak terlihat (misalnya gelap dengan teks hitam), saya sempat berpikir bagaimana kalau semua tombol diperiksa satu per satu sebelum rilis. Atau mungkin buat aturan internal yang dibagikan ke seluruh tim bahwa tombol gelap tidak boleh memakai teks hitam. Perbedaan antara kontras kognitif dan kontras matematis itu menarik. Saya akan menerapkannya ke alur kerja saya.
Memeriksa semua tombol memang mungkin, tetapi dengan cara seperti itu masa uji regresi sebelum rilis bisa memakan waktu berminggu-minggu, bahkan berbulan-bulan. Di proyek besar, jumlah tombol mudah sekali mencapai ribuan, dan banyak tombol hanya muncul pada kombinasi opsi atau alur kerja tertentu
Jika merujuk APCA, Anda bisa menghitung kontras berbasis persepsi
Saya pernah membuat gaya tombol saat warna sistem sedang populer. Tampilannya bagus, tapi karena saya tidak tahu bagaimana rasio kontrasnya, ada yang menghitungnya lewat JavaScript dengan getComputedStyle. Jika kontrasnya buruk, kami memakai kandidat warna kedua, atau kalau terpaksa memperkuat efek kontras di sekitar teks dengan text-shadow. Saya lupa cara perhitungannya, tapi sepertinya bisa juga dengan membandingkan rata-rata tiga nilai RGB. Untuk warna biru, nilai rata-ratanya akan lebih rendah, jadi mungkin teks putih bisa diprioritaskan.
Setidaknya akan bagus jika ada rekomendasi warna yang baik untuk pseudo-class seperti active, focus, hover, link, visited pada tema light/dark. Material UI bahkan menambahkan status disabled, before, dan after.
Dulu saya pernah membuat tutorial video tentang cara memilih teks hitam/putih berdasarkan warna latar. Cara saya sederhana: warnanya diubah menjadi skala abu-abu lalu ditentukan apakah sebaiknya memakai hitam atau putih. Proyek yang menyenangkan. Kemampuan saya membuat video kurang bagus.
https://youtu.be/tUJvE4xfTgo?si=vFlegFA_7lzijfSR (peringatan: berbahasa Portugis)
https://news.ycombinator.com/item?id=44015990
Videonya juga tampak lumayan. Kodenya terlihat bagus, tetapi saya tidak bisa menilai isinya karena saya tidak mengerti bahasa Portugis.
Jika Anda sudah memilih sendiri keseluruhan skema warna, saya bingung kenapa memilih warna teks tombol kontras dianggap lebih mudah daripada memilihnya sendiri sejak awal. Fitur ini tampaknya hanya dibutuhkan dalam situasi yang sangat ekstrem, ketika warna latar dipilih secara acak tetapi warna depan (warna teks tombol) justru tidak bisa dipilih. Situasi yang benar-benar bermasalah adalah teks di atas gambar atau latar yang beragam, yang harus selalu tetap terbaca, dan fitur ini sama sekali tidak menanganinya. Jadi ini tampak seperti fitur yang hanya berguna dalam situasi yang terbatas seperti itu, tetapi sampai perlu menciptakan kata kerja baru untuknya, padahal fiturnya cuma memilih hitam/putih dan memakai algoritma kontras terburuk (WCAG 2). Benar-benar luar biasa.
Sayang sekali jika sebuah alat langsung diabaikan hanya karena belum pernah menemui situasi untuk memakainya. Ada banyak situs web tempat pengguna memilih warna sesuka hati atau warna diekstrak dari materi yang diunggah. Situs yang memperhatikan aksesibilitas harus menghitung kontras secara otomatis untuk kasus seperti ini. Jika fitur CSS bawaan seperti ini tersedia, aksesibilitas dasar jadi lebih mudah diterapkan. Tentu saja ini tidak membatasi pengembang yang ingin membangun pengalaman yang lebih canggih. Akan lebih baik jika bisa lebih dapat dikustomisasi seperti paket npm contrast-color, tetapi seperti dijelaskan di blog, algoritma yang memilih hanya hitam/putih ini baru langkah pertama dan ada rencana peningkatan ke depannya.
Contoh: https://coolors.co/8fbfe0-7c77b9-1d8a99-0bc9cd-14fff7
Terkait kritik bahwa algoritma pemilihan kontrasnya kurang bagus, artikel itu dengan jelas menyatakan bahwa ia mengikuti algoritma WCAG 2, dan ketika WCAG 3 sudah distandardisasi nanti, algoritma tersebut bisa dengan mudah diganti ke yang baru
Saya penasaran apakah ada alternatif build-time untuk fitur seperti ini yang bisa diterapkan di SASS, Tailwind, dan sebagainya. Sepertinya perlu waktu sebelum fitur ini diadopsi penuh, dan saya juga khawatir apakah implementasinya akan konsisten di tiap platform.