Properti color-scheme menunjukkan skema warna (seperti terang atau gelap) yang didukung halaman Anda. Hal ini memberi tahu browser bahwa browser dapat otomatis menerapkan tema pada elemen UI native—seperti scrollbar, kontrol formulir, dan latar belakang kanvas default—agar sesuai dengan desain situs Anda dan membantu meminimalkan flash putih selama pemuatan awal.
Penerapan
1. Mendeklarasikan skema yang didukung dalam HTML
WAJIB: Untuk membantu mencegah "flash of un-themed content" (FOUC), tempatkan tag <meta> di <head> untuk memastikan browser mengetahui tema yang Anda dukung bahkan sebelum mulai merender. Meskipun tag <meta> ini membantu menghindari FOUC dengan menetapkan warna kanvas awal lebih awal, tag ini mungkin tidak sepenuhnya menghilangkan kedipan di semua browser atau kondisi pemuatan.
<!-- MANDATORY: Declare support for both light and dark themes -->
<meta name="color-scheme" content="light dark">
2. Menerapkan skema warna di seluruh halaman ke :root atau html CSS
WAJIB: Terapkan properti color-scheme ke elemen html atau pseudo-class :root. Browser secara khusus melihat elemen root untuk menentukan tema seluruh area pandang—termasuk scrollbar root dan latar belakang "kanvas" awal. Jika hanya diterapkan ke body, platform UI global ini mungkin tetap dalam mode terang karena body tidak mengontrol konteks rendering jendela.
/* MANDATORY: Apply color-scheme to :root or html for viewport-wide theming */
:root {
/* MANDATORY: Automatically adapt native UI to user system preferences */
color-scheme: light dark;
}
3. Menentukan token warna terang dan gelap
Anda dapat menggunakan fungsi light-dark() untuk menentukan token warna yang otomatis beradaptasi dengan nilai color-scheme yang berbeda.
Sebaiknya Anda juga menyimpan nilai warna mentah di properti kustom terpisah, sehingga lebih mudah untuk menggabungkannya dengan berbagai cara (dan memudahkan perilaku penggantian, jika diperlukan).
Untuk kontrol lebih besar atas warna UI bawaan seperti accent-color atau scrollbar-color, penulis dapat secara opsional menambahkan warna dinamis mereka sendiri dengan menggunakan properti kustom dan/atau fungsi light-dark(). Fungsi ini otomatis memilih warna yang benar berdasarkan color-scheme elemen yang dihitung dan menghilangkan kebutuhan akan kueri media yang redundan, tetapi tidak diperlukan untuk implementasi dasar.
:root {
--color-brand-light: oklch(45% 0.23 270);
--color-brand-dark: oklch(85% 0.15 210);
--color-brand-text-light: white;
--color-brand-text-dark: oklch(40% 0.23 270);
--color-brand: light-dark(var(--color-brand-light), var(--color-brand-dark));
--color-brand-text: light-dark(var(--color-brand-text-light), var(--color-brand-text-dark));
/* MANDATORY: Automatically adapt native UI to user system preferences */
color-scheme: light dark;
}
button.primary {
/* These automatically adapt to color scheme */
background-color: var(--color-brand);
color: var(--color-brand-text);
}
OPSIONAL: Tersedia sejumlah warna sistem, yang juga otomatis beradaptasi dengan skema warna yang digunakan (dan mode warna lainnya, misalnya warna paksa), seperti canvas, canvastext, accentcolor (periksa dukungan), buttonborder, dll. Warna ini biasanya terlalu terbatas untuk berguna, di luar kasus yang sangat spesifik saat Anda perlu mencocokkan persis UI browser default tertentu atau sebagai pengganti/default.
OPSIONAL: Sesuaikan pasangan warna dengan konteks
Meskipun mengganti setelan default sistem, sebaiknya gunakan kueri media prefers-color-scheme untuk menentukan pasangan warna yang berbeda yang mempertimbangkan warna browser dan chrome OS di sekitar halaman (atau halaman di sekitarnya, jika halaman digunakan sebagai iframe).
Misalnya, gunakan tema terang yang sedikit lebih redup saat setelan sistem adalah dark, atau tema gelap yang lebih kontras saat setelan sistem adalah light, sehingga halaman tidak terlalu mencolok secara visual dibandingkan dengan UI di sekitarnya.
Penyesuaian UI browser yang mendetail
Setelan color-scheme sudah menyesuaikan UI browser dengan skema warna yang digunakan, tetapi setelan ini akan menggunakan warna default OS dan/atau warna sistem yang mungkin tidak sepenuhnya selaras dengan desain situs.
Browser modern mengekspos beberapa hook penyesuaian yang mendetail untuk hal ini.
Jangan menerapkan ulang kontrol native hanya untuk menyesuaikan tampilannya tanpa menggunakan hook penyesuaian yang disediakan browser modern.
Menetapkan warna aksen
Beberapa UI browser (misalnya, kotak centang atau penggeser yang dicentang) menggunakan warna aksen.
Warna ini ditetapkan ke setelan OS secara default, tetapi Anda dapat menggunakan properti accent-color untuk menetapkannya ke warna yang lebih sesuai dengan halaman, seperti warna merek halaman.
html {
accent-color: light-dark(var(--color-accent-light), var(--color-accent-dark));
}
Masalah yang perlu diperhatikan saat menggunakan accent-color
Rendering browser untuk accent-color bervariasi.
Untuk indikator yang umumnya digambar di atas latar belakang warna aksen, seperti tanda kotak centang dan titik tombol pilihan, browser dapat menerapkan perlakuan yang berbeda:
- Chromium dan Firefox umumnya memilih warna indikator yang kontras.
- Safari dapat mempertahankan indikator putih dalam mode terang atau indikator hitam dalam mode gelap, sekaligus mengubah warna aksen di belakangnya. Penyesuaian ini tidak selalu memberikan kontras yang memadai untuk setiap warna yang disediakan, jadi uji kombinasi penting di Safari, termasuk skema warna terang dan gelap. Jangan berasumsi bahwa Safari akan otomatis memilih warna indikator yang memberikan kontras terbaik.
Warna scrollbar
Anda dapat menggunakan scrollbar-color bersama dengan light-dark() untuk menetapkan warna scrollbar kustom yang beradaptasi dengan skema warna yang digunakan.
:root {
--color-scrollbar-track: light-dark(#eee, #222);
--color-scrollbar-thumb: light-dark(#999, #666);
scrollbar-color: var(--color-scrollbar-thumb) var(--color-scrollbar-track);
}
Masalah yang perlu diperhatikan saat menggunakan scrollbar-color
- JANGAN menganimasikan atau mentransisikan
scrollbar-color. Bug WebKit menyebabkan scrollbar berkedip setiap kaliscrollbar-colorberubah. - Di macOS, properti
scrollbar-color(standar) dan::-webkit-scrollbar(lama) diabaikan secara default karena macOS menggunakan scrollbar "overlay" native. Anda HARUS menyambungkan warna kustom denganscrollbar-width(misalnya,thinatauauto) untuk memaksa macOS merendernya. - Meskipun
scrollbar-widthditerapkan, scrollbar overlay macOS merender jalur (gutter) sebagai transparan secara default. Jika desain memerlukan warna latar belakang trek yang terlihat di MacOS, Anda HARUS menerapkanscrollbar-gutter: stable;ke penampung yang dapat di-scroll, tetapi perhatikan bahwa warna tersebut hanya muncul setelah pengguna mengarahkan kursor ke scrollbar. - Meskipun dengan
scrollbar-gutter: stable, trek mungkin transparan di MacOS. Thumb tidak boleh bergantung pada warna trek agar terlihat.
Penyesuaian lebih lanjut
Sebagian besar UI browser mengekspos elemen pseudo untuk menyesuaikan tampilannya sepenuhnya, seperti:
::placeholder::spelling-error::grammar-error::selection::search-text::target-text::file-selector-button
Anda dapat menggunakan warna light-dark() pada salah satu warna ini untuk menerapkan warna yang beradaptasi dengan skema warna yang digunakan.
4. Memvariasikan gambar untuk mode terang dan gelap
Untuk gambar CSS, light-dark() juga dapat digunakan untuk memberikan nilai gambar yang berbeda.
PENTING: Kedua nilai di light-dark() harus berjenis sama. Anda tidak dapat menggabungkan warna dengan gambar.
Jika salah satu dari keduanya harus berupa gambar, gunakan image(<color>) untuk menggabungkan nilai warna.
Deteksi tema berbasis JS
Sebagian besar percabangan skema warna harus dilakukan di CSS, yang otomatis beradaptasi dengan perubahan.
Setiap JS yang membaca matchMedia("(prefers-color-scheme: dark)").matches JUGA HARUS menangani peristiwa change-nya karena preferensi sistem dapat berubah kapan saja.
OPSIONAL: Menerapkan tombol skema warna
Jika ingin mengizinkan pengguna mengganti setelan default sistem secara manual untuk situs ini, Anda dapat menerapkan tombol mode gelap. Sebagian besar situs tidak memerlukan tombol persisten di UI situs. Biasanya, cukup gunakan skema warna sistem secara default, dengan setelan opsional di platform setelan terpisah. Lihat Tombol mode gelap untuk mengetahui praktik terbaik seputar penerapan tombol mode gelap (persisten atau tidak).
OPSIONAL: Penggantian khusus komponen
Anda dapat mengganti tema global untuk elemen tertentu dengan menetapkan color-scheme pada elemen tersebut.
Untuk mengetahui informasi selengkapnya dan hal-hal yang perlu diperhatikan, lihat Tema terang/gelap khusus komponen.
Masalah umum yang perlu diperhatikan
Masalah yang perlu diperhatikan saat menggunakan color-scheme
- Chrome dan Firefox mematuhi
color-schemeuntuk iframe: keduanya merender halaman tersemat dalam skema warna yang benar dan menyesuaikan kueri mediaprefers-color-schemehalaman tersemat untuk mencerminkancolor-schemekonteks penyematan. Safari tidak melakukannya, dan me-resolveprefers-color-schemeke setelan sistem bahkan di dalam iframe.- Jika Anda mengontrol induk dan iframe: teruskan skema warna induk ke iframe secara eksplisit — melalui parameter URL (
?theme=dark) pada waktu pembuatan iframe, atau melaluipostMessage()(yang juga memungkinkan Anda bereaksi terhadap perubahan runtime). Di iframe, tetapkan class di<html>(dan/ataucolor-schemedi:root) dari sinyal tersebut, bukan mengandalkanprefers-color-scheme. - Jika Anda hanya mengontrol halaman yang disematkan: tidak ada cara yang andal untuk mendeteksi
color-schemekonteks penyematan dari dalam iframe di Safari. Ekspos parameter tema eksplisit di API sematan Anda (misalnya, string kueri atau protokolpostMessage) dan dokumentasikan untuk penyemat.
- Jika Anda mengontrol induk dan iframe: teruskan skema warna induk ke iframe secara eksplisit — melalui parameter URL (
Strategi penggantian
Penggantian & dukungan browser untuk skema warna
Properti color-scheme adalah progressive enhancement.
Browser yang tidak mendukungnya akan mengabaikan properti ini dan menggunakan UI mode terang default.
Untuk menyesuaikan dengan preferensi pengguna di browser lama, gunakan kueri media prefers-color-scheme untuk memberikan warna yang berbeda saat mode gelap lebih disukai.
- GUNAKAN kueri media untuk mengaktifkan properti kustom di
:rootatauhtml - Hindari penggunaan kueri media pada setiap komponen, kecuali jika komponen tersebut memerlukan jenis penyesuaian mode gelap yang sangat spesifik selain warna.
:root {
/* Define brand colors for each mode */
--color-brand-light: #0056b3;
--color-brand-dark: #00e5ff;
--color-brand: var(--color-brand-light);
/* MANDATORY: Fallback for browsers without light-dark support */
@media (prefers-color-scheme: dark) {
--color-brand: var(--color-brand-dark);
}
/* Ignored in older browsers */
color-scheme: light dark;
}
button.primary {
background-color: var(--color-brand);
}
Penggantian & dukungan browser untuk light-dark()
Untuk browser yang mendukung color-scheme, tetapi belum mendukung light-dark(), versi warna terang dan gelap harus ditentukan terlebih dahulu sebagai properti kustom, dan kueri media prefers-color-scheme harus digunakan untuk menetapkan warna untuk masing-masing mode seperti dalam contoh di bawah:
:root {
/* Define browser UI accent color for each mode */
--brand-accent-light: #0056b3;
--brand-accent-dark: #00e5ff;
--accent-color: var(--brand-accent-light);
/* MANDATORY: Fallback for browsers without light-dark support */
@media (prefers-color-scheme: dark) {
--accent-color: var(--brand-accent-dark);
}
/* OPTIONAL: use light-dark() for more control of built-in UI colors */
@supports (color: light-dark(white, black)) {
--accent-color: light-dark(var(--brand-accent-light), var(--brand-accent-dark));
}
/* MANDATORY: Automatically adapt native UI to user system preferences */
color-scheme: light dark;
/* Example inherited color property */
accent-color: var(--accent-color);
}
pre, code {
color-scheme: dark;
/* **Mandatory**: any inherited color properties must be set again, even if to the same design tokens */
accent-color: var(--accent-color);
}
Penggantian & dukungan browser untuk nilai gambar light-dark()
Untuk browser yang tidak mendukung light-dark() untuk gambar, gunakan image-set() sebagai tombol:
berikan type() dari properti kustom untuk setiap opsi, dan tetapkan opsi yang tidak aktif ke jenis MIME yang tidak didukung agar browser menghapus opsi tersebut.
Opsi aktif mendapatkan nilai kosong, sehingga merupakan opsi image-set() biasa tanpa type().
Tentukan tombol akses sekali di :root. Setiap situs penggunaan kemudian hanya memerlukan kedua image secara inline, seperti light-dark().
:root {
--light-type: ;
--dark-type: type("image/do-not-use");
/* MANDATORY: Fallback for browsers without light-dark() image support */
@media (prefers-color-scheme: dark) {
--light-type: type("image/do-not-use");
--dark-type: ;
}
}
.hero {
background-image: image-set(url(hero-light.png) var(--light-type), url(hero-dark.png) var(--dark-type));
@supports (background-image: light-dark(url("a"), url("b"))) {
background-image: light-dark(url(hero-light.png), url(hero-dark.png));
}
}
- Hanya gambar yang dipilih yang didownload.
- Resolusi masih berfungsi:
image-set(url(a-1x.png) 1x var(--light-type), url(a-2x.png) 2x var(--light-type), url(b-1x.png) 1x var(--dark-type), url(b-2x.png) 2x var(--dark-type)). - JANGAN gunakan
type("")untuk opsi aktif. Browser memperlakukan string kosong sebagai tidak didukung dan menghapus setiap opsi. - Tidak seperti
light-dark(), tombol tidak mengikuticolor-schemeyang ditetapkan pada subhierarki. Tombol manual, atau subhierarki apa pun yang menetapkancolor-scheme, HARUS juga membalik--light-typedan--dark-type.
Alternatif: satu properti kustom per gambar
Lebih sederhana jika hanya beberapa gambar yang bervariasi, tetapi setiap gambar memerlukan cabang kueri medianya sendiri, dan tombol manual harus mengaktifkan setiap gambar.
:root {
--hero-image: url(hero-light.png);
@media (prefers-color-scheme: dark) {
--hero-image: url(hero-dark.png);
}
@supports (background-image: light-dark(url("a"), url("b"))) {
--hero-image: light-dark(url(hero-light.png), url(hero-dark.png));
}
}
.hero {
background-image: var(--hero-image);
}
Penggantian & dukungan browser untuk image()
Gunakan gradien dengan satu perhentian warna dan tanpa posisi, misalnya linear-gradient(blue).
Untuk dukungan browser yang lebih luas, Anda dapat secara eksplisit memberikan posisi 0 100% untuk perhentian warna tunggal, misalnya linear-gradient(blue 0 100%).
Penggantian & dukungan browser untuk scrollbar-color
Fitur ini adalah progressive enhancement dan tidak selalu memerlukan penggantian.
Jika gaya visual penting dan target Baseline pengguna adalah "Baseline Tersedia Luas" atau yang lebih lama, Anda HARUS menyertakan elemen semu ::-webkit-scrollbar non-standar sebagai pengganti.
Gabungkan penggantian lama dalam blok @supports not (scrollbar-color: auto) untuk mencegah konflik antara properti standar dan pemilih WebKit lama di browser yang mendukung keduanya secara native.
Jika Anda menggunakan properti kustom untuk menentukan warna, properti ini akan otomatis diwariskan ke pemilih WebKit lama. Anda TIDAK perlu menduplikasinya.
/* Legacy fallback for WebKit/Blink browsers */
@supports not (scrollbar-color: auto) {
.scroller::-webkit-scrollbar {
/* Must define base size in WebKit for custom colors to be visual */
width: 12px;
height: 12px;
}
.scroller::-webkit-scrollbar-thumb {
background: var(--scrollbar-thumb);
}
.scroller::-webkit-scrollbar-track {
background: var(--scrollbar-track);
}
}
Penggantian & dukungan browser untuk accent-color
Properti accent-color adalah progressive enhancement.
Browser yang tidak mendukung properti ini akan mengabaikannya dan menggunakan warna UI default.