Suis Mod Gelap
Ikut skema warna sistem secara lalai, benarkan pengguna menukarnya, ingat pilihan mereka, dan elakkan kilatan putih semasa halaman dimuatkan.
Pratonton langsung Buka dalam Playground
:root {
color-scheme: light;
--bg: #ffffff;
--text: #1c1c1e;
--muted: #5b5b66;
--surface: #f2f2f5;
}
:root[data-theme="dark"] {
color-scheme: dark; /* dark scrollbars and form controls too */
--bg: #121214;
--text: #ececf1;
--muted: #a1a1aa;
--surface: #1f1f23;
}
body {
background: var(--bg);
color: var(--text);
}// Put this in <head>, BEFORE your stylesheet, so the right theme
// is applied before the first paint (no white flash).
(function () {
let saved = null;
try {
saved = localStorage.getItem("theme");
} catch {
// storage blocked — just follow the system
}
const prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
document.documentElement.dataset.theme = saved || (prefersDark ? "dark" : "light");
})();const STORAGE_KEY = "theme";
const media = window.matchMedia("(prefers-color-scheme: dark)");
const toggle = document.getElementById("theme-toggle");
function savedTheme() {
try {
return localStorage.getItem(STORAGE_KEY);
} catch {
return null;
}
}
function applyTheme(theme) {
document.documentElement.dataset.theme = theme;
toggle.setAttribute("aria-pressed", String(theme === "dark"));
}
toggle.addEventListener("click", () => {
const next = document.documentElement.dataset.theme === "dark" ? "light" : "dark";
try {
localStorage.setItem(STORAGE_KEY, next);
} catch {
// can't save — the toggle still works for this visit
}
applyTheme(next);
});
// Follow system changes only while the user hasn't chosen
media.addEventListener("change", (event) => {
if (!savedTheme()) applyTheme(event.matches ? "dark" : "light");
});
applyTheme(savedTheme() || (media.matches ? "dark" : "light"));Mod gelap yang baik ada tiga lapisan: pemboleh ubah CSS simpan warna, atribut data-theme pada <html> memilih satu set, dan sedikit JavaScript menentukan yang mana — pilihan yang disimpan jika ada, jika tiada ikut pilihan sistem operasi.
Baris demi baris
- Komponen hanya guna
var(--bg),var(--text)… Menukar tema mengubah pemboleh ubah di satu tempat sahaja; bahagian lain tak perlu tahu. color-scheme: darkberitahu pelayar supaya lukis bahagiannya sendiri (scrollbar, input, pemilih tarikh) dalam warna gelap juga.- Skrip init kecil ini berjalan dalam
<head>sebelum apa-apa dilukis, jadi pengguna mod gelap tak nampak halaman putih dahulu. Sebab itu ia diasingkan daripada skrip suis, yang perlukan butang sudah wujud. aria-pressedjadikan butang biasa sebagai butang togol untuk pembaca skrin ("Dark mode, toggle button, pressed").- Setiap panggilan
localStoragedibalut dengantry/catch: storan boleh dimatikan atau penuh, dan suis masih patut berfungsi untuk lawatan semasa. - Listener
changepadamatchMediaterus mengikut sistem (contohnya mod gelap automatik waktu malam) — tetapi hanya sehingga pengguna membuat pilihan.
Semak kontras dalam kedua-dua tema. Mod gelap bukan sekadar warna terbalik — hitam pekat dengan teks putih pekat terlalu tajam; kelabu yang sedikit cerah lebih selesa untuk mata.
Cara guna
<!DOCTYPE html>
<html lang="en">
<head>
<script src="theme-init.js"></script>
<link rel="stylesheet" href="theme.css">
</head>
<body>
<button type="button" id="theme-toggle" aria-pressed="false">Dark mode</button>
<script src="theme-toggle.js"></script>
</body>
</html>