Meningkatkan gaya default mode gelap dengan properti CSS skema warna dan tag meta yang sesuai

Properti CSS color-scheme dan tag meta yang sesuai memungkinkan developer memilih halaman mereka untuk menggunakan setelan default khusus tema dari stylesheet agen pengguna.

Latar belakang

Fitur media preferensi pengguna prefers-color-scheme

Fitur media preferensi pengguna prefers-color-scheme memberi developer kontrol penuh atas tampilan halaman mereka. Jika Anda belum memahaminya, baca artikel saya prefers-color-scheme: Halo kegelapan, teman lamaku, tempat saya mendokumentasikan semua yang saya ketahui tentang cara membuat pengalaman mode gelap yang luar biasa.

Satu bagian teka-teki yang hanya disebutkan secara singkat dalam artikel ini adalah properti CSS color-scheme dan tag meta yang sesuai dengan nama yang sama. Keduanya memudahkan Anda sebagai developer dengan memungkinkan Anda memilih halaman untuk menggunakan setelan default khusus tema dari stylesheet agen pengguna, seperti, misalnya, kontrol formulir, scrollbar, serta warna sistem CSS. Pada saat yang sama, fitur ini mencegah browser menerapkan transformasi apa pun dengan sendirinya.

Dukungan browser

prefers-color-scheme

Dukungan Browser

  • Chrome: 76.
  • Edge: 79.
  • Firefox: 67.
  • Safari: 12.1.

Sumber

color-scheme

Dukungan Browser

  • Chrome: 81.
  • Edge: 81.
  • Firefox: 96.
  • Safari: 13.

Sumber

Stylesheet agen pengguna

Sebelum melanjutkan, izinkan saya menjelaskan secara singkat apa yang dimaksud dengan stylesheet agen pengguna. Sebagian besar waktu, Anda dapat menganggap kata agen pengguna (UA) sebagai cara yang bagus untuk mengatakan browser. Stylesheet UA menentukan tampilan dan nuansa default halaman. Seperti namanya, stylesheet UA adalah sesuatu yang bergantung pada UA yang dimaksud. Anda dapat melihat lembar gaya UA Chrome (dan Chromium) dan membandingkannya dengan Firefox atau Safari (dan WebKit). Biasanya, stylesheet UA setuju dengan sebagian besar hal. Misalnya, semuanya membuat link berwarna biru, teks umum berwarna hitam, dan warna latar belakang berwarna putih, tetapi ada juga perbedaan penting (dan terkadang menjengkelkan), misalnya, cara mereka menata gaya kontrol formulir.

Pelajari lebih lanjut stylesheet UA WebKit dan fungsinya terkait mode gelap. (Lakukan penelusuran teks lengkap untuk "dark" di stylesheet.) Default yang disediakan oleh stylesheet berubah berdasarkan apakah mode gelap aktif atau nonaktif. Untuk mengilustrasikannya, berikut adalah salah satu aturan CSS tersebut yang menggunakan pseudo class :matches dan variabel internal WebKit seperti -apple-system-control-background, serta perintah preprocessor internal WebKit #if defined:

input,
input:matches([type="password"], [type="search"]) {
  -webkit-appearance: textfield;
  #if defined(HAVE_OS_DARK_MODE_SUPPORT) &&
      HAVE_OS_DARK_MODE_SUPPORT
    color: text;
    background-color: -apple-system-control-background;
  #else
    background-color: white;
  #endif
  /* snip */
}

Anda akan melihat beberapa nilai non-standar untuk properti color dan background-color di atas. text maupun -apple-system-control-background bukan warna CSS yang valid. Warna ini adalah warna semantik internal WebKit.

Ternyata, CSS memiliki warna sistem semantik yang terstandardisasi. Nilai ini ditentukan dalam CSS Color Module Level 4. Misalnya, Canvas (jangan dikelirukan dengan tag <canvas>) adalah untuk latar belakang konten atau dokumen aplikasi, sedangkan CanvasText adalah untuk teks dalam konten atau dokumen aplikasi. Keduanya saling terkait dan tidak boleh digunakan secara terpisah.

Stylesheet UA dapat menggunakan warna sistem semantik standar atau warna eksklusifnya sendiri, untuk menentukan cara elemen HTML dirender secara default. Jika sistem operasi disetel ke mode gelap atau menggunakan tema gelap, CanvasText (atau text) akan disetel secara kondisional ke putih, dan Canvas (atau -apple-system-control-background) akan disetel ke hitam. Stylesheet UA kemudian menetapkan CSS berikut hanya sekali, dan mencakup mode terang dan gelap.

/**
  Not actual UA stylesheet code.
  For illustrative purposes only.
*/
body {
  color: CanvasText;
  background-color: Canvas
}

Properti CSS color-scheme

Spesifikasi CSS Color Adjustment Module Level 1 memperkenalkan model dan kontrol atas penyesuaian warna otomatis oleh agen pengguna dengan tujuan menangani preferensi pengguna seperti mode gelap, penyesuaian kontras, atau skema warna tertentu yang diinginkan.

Properti color-scheme yang ditentukan di dalamnya memungkinkan elemen menunjukkan skema warna yang nyaman untuk dirender. Nilai ini dinegosiasikan dengan preferensi pengguna, sehingga menghasilkan skema warna yang dipilih yang memengaruhi hal-hal antarmuka pengguna (UI) seperti warna default kontrol form dan panel scroll, serta nilai yang digunakan dari warna sistem CSS. Nilai-nilai berikut saat ini didukung:

  • normal Menunjukkan bahwa elemen sama sekali tidak mengetahui skema warna, sehingga elemen harus dirender dengan skema warna default browser.

  • [ light | dark ]+ Menunjukkan bahwa elemen mengetahui dan dapat menangani skema warna yang tercantum, serta menyatakan preferensi yang diurutkan di antara skema warna tersebut.

Dalam daftar ini, light mewakili skema warna terang, dengan warna latar belakang terang dan warna latar depan gelap, sedangkan dark mewakili sebaliknya, dengan warna latar belakang gelap dan warna latar depan terang.

Untuk semua elemen, rendering dengan skema warna akan menyebabkan warna yang digunakan di semua UI yang disediakan browser untuk elemen cocok dengan intent skema warna. Contohnya adalah scrollbar, garis bawah periksa ejaan, kontrol formulir, dll.

Pada elemen :root, rendering dengan skema warna juga harus memengaruhi warna permukaan kanvas (yaitu, warna latar belakang global), nilai awal properti color, dan nilai warna sistem yang digunakan, serta harus memengaruhi scroll bar area pandang.

/*
  The page supports both dark and light color schemes,
  and the page author prefers dark.
*/
:root {
  color-scheme: dark light;
}

Tag meta color-scheme

Untuk mematuhi properti CSS color-scheme, CSS harus didownload terlebih dahulu (jika direferensikan melalui <link rel="stylesheet">) dan diuraikan. Untuk membantu agen pengguna merender latar belakang halaman dengan skema warna yang diinginkan segera, nilai color-scheme juga dapat diberikan dalam elemen <meta name="color-scheme">.

<!--
  The page supports both dark and light color schemes,
  and the page author prefers dark.
-->
<meta name="color-scheme" content="dark light">

Menggabungkan color-scheme dan prefers-color-scheme

Karena tag meta dan properti CSS (jika diterapkan ke elemen :root) akhirnya menghasilkan perilaku yang sama, sebaiknya tentukan skema warna melalui tag meta, sehingga browser dapat mengadopsi skema yang diinginkan dengan lebih cepat.

Meskipun untuk halaman dasar pengukuran absolut tidak diperlukan aturan CSS tambahan, dalam kasus umum Anda harus selalu menggabungkan color-scheme dengan prefers-color-scheme. Misalnya, warna CSS WebKit eksklusif -webkit-link, yang digunakan oleh WebKit dan Chrome untuk rgb(0,0,238) biru link klasik, memiliki rasio kontras 2,23:1 yang tidak memadai pada latar belakang hitam dan gagal persyaratan WCAG AA serta WCAG AAA.

Saya telah membuka bug untuk Chrome, WebKit, dan Firefox serta masalah meta pada HTML Standard untuk memperbaikinya.

Interaksi dengan prefers-color-scheme

Interaksi properti CSS color-scheme dan tag meta yang sesuai dengan fitur media preferensi pengguna prefers-color-scheme mungkin tampak membingungkan pada awalnya. Faktanya, keduanya sangat cocok untuk digunakan bersama. Hal yang paling penting untuk dipahami adalah bahwa color-scheme secara eksklusif menentukan tampilan default, sedangkan prefers-color-scheme menentukan tampilan bergaya. Untuk memperjelasnya, asumsikan halaman berikut:

<head>
  <meta name="color-scheme" content="dark light">
  <style>
    fieldset {
      background-color: gainsboro;
    }
    @media (prefers-color-scheme: dark) {
      fieldset {
        background-color: darkslategray;
      }
    }
  </style>
</head>
<body>
  <p>
    Lorem ipsum dolor sit amet, legere ancillae ne vis.
  </p>
  <form>
    <fieldset>
      <legend>Lorem ipsum</legend>
      <button type="button">Lorem ipsum</button>
    </fieldset>
  </form>
</body>

Kode CSS inline di halaman menetapkan background-color elemen <fieldset> ke gainsboro secara umum, dan ke darkslategray jika pengguna lebih memilih skema warna dark sesuai dengan fitur media preferensi pengguna prefers-color-scheme.

Melalui elemen <meta name="color-scheme" content="dark light">, halaman memberi tahu browser bahwa halaman mendukung tema gelap dan terang, dengan preferensi untuk tema gelap.

Bergantung pada apakah sistem operasi disetel ke mode gelap atau terang, seluruh halaman akan tampak terang dalam warna gelap, atau sebaliknya, berdasarkan stylesheet agen pengguna. Tidak ada CSS tambahan yang disediakan developer untuk mengubah teks paragraf atau warna latar belakang halaman.

Perhatikan bagaimana background-color elemen <fieldset> berubah berdasarkan apakah mode gelap diaktifkan, dengan mengikuti aturan dalam stylesheet inline yang disediakan developer di halaman. Nilainya adalah gainsboro atau darkslategray.

Halaman dalam mode terang.
Mode terang: Gaya yang ditentukan oleh developer dan agen pengguna. Teks berwarna hitam dan latar belakang berwarna putih sesuai dengan stylesheet agen pengguna. background-color elemen <fieldset> adalah gainsboro sesuai stylesheet developer inline.
Halaman dalam mode gelap.
Mode gelap: Gaya yang ditentukan oleh developer dan agen pengguna. Teks berwarna putih dan latar belakang berwarna hitam sesuai dengan stylesheet agen pengguna. background-color elemen <fieldset> adalah darkslategray sesuai dengan stylesheet developer yang disisipkan.

Tampilan elemen <button> dikontrol oleh stylesheet agen pengguna. color-nya disetel ke warna sistem ButtonText, dan background-color serta empat border-color-nya disetel ke warna sistem ButtonFace.

Halaman mode terang yang menggunakan properti ButtonFace.
Mode terang: background-color dan berbagai border-color ditetapkan ke warna sistem ButtonFace.

Sekarang perhatikan bagaimana border-color elemen <button> berubah. Nilai yang dihitung untuk border-top-color dan border-bottom-color beralih dari rgba(0, 0, 0, 0.847) (kehitaman) ke rgba(255, 255, 255, 0.847) (keputihan), karena agen pengguna memperbarui ButtonFace secara dinamis berdasarkan skema warna. Hal yang sama berlaku untuk color elemen <button> yang disetel ke ButtonText warna sistem yang sesuai.

Menunjukkan bahwa nilai warna yang dihitung cocok dengan ButtonFace.
Mode terang: Nilai yang dihitung dari border-top-color dan border-bottom-color yang keduanya ditetapkan ke ButtonFace di stylesheet agen pengguna kini menjadi rgba(0, 0, 0, 0.847).
Menunjukkan bahwa nilai warna yang dihitung masih cocok dengan ButtonFace saat dalam mode gelap.
Mode gelap: Nilai komputasi border-top-color dan border-bottom-color yang disetel ke ButtonFace di stylesheet agen pengguna sekarang menjadi rgba(255, 255, 255, 0.847).

Demo

Anda dapat melihat efek color-scheme yang diterapkan ke sejumlah besar elemen HTML dalam demo di Glitch. Demo ini sengaja menampilkan pelanggaran WCAG AA dan WCAG AAA dengan warna link yang disebutkan dalam peringatan di atas.

Demo saat dalam mode terang.
Demo diubah ke color-scheme: light.
Demo saat dalam mode gelap.
Demo diubah ke color-scheme: dark. Perhatikan pelanggaran WCAG AA dan WCAG AAA dengan warna link.

Ucapan terima kasih

Properti CSS color-scheme dan tag meta yang sesuai diterapkan oleh Rune Lillesveen. Rune juga merupakan rekan editor spesifikasi CSS Color Adjustment Module Level 1. Gambar hero oleh Philippe Leone di Unsplash.