Įjungėte tamsią temą, o kiekvieną kartą perkraunant puslapis akimirką sužybsi baltai ir tik tada patamsėja. Tai dažniausia temos jungiklio klaida, ir ji ištaisoma vienu mažyčiu scenarijumi tinkamoje vietoje. Toliau – visas receptas: kodas, kurį galima nukopijuoti, paaiškinimas, kaip tai veikia, ir būdas patiems patikrinti rezultatą.
Ką gausite #
- Numatytai tema atitinka sistemos temą (šviesią arba tamsią) ir veikia net išjungus JavaScript.
- Mygtukas perjungia temą, o pasirinkimas įsimenamas naršyklėje.
- Išsaugotas pasirinkimas pritaikomas dar prieš pirmą piešimą: perkraunant jokio balto blyksnio.



Kodėl puslapis sužybsi #
Naršyklė piešia puslapį skaitydama HTML. Jei naudotojo pasirinkimą pritaiko scenarijus puslapio pabaigoje arba po įkėlimo, naršyklė spėja nupiešti šviesųjį variantą ir tik tada jį perpiešia. Pasirinkimas turi būti žinomas dar prieš pasirodant pirmam taškui, todėl scenarijus turi stovėti pačioje puslapio pradžioje,head dalyje.1 žingsnis. Praneškite, kad svetainė turi abi temas #
Įhead įdėkite meta eilutę, o iškart po jos – mažytį scenarijų. Jis perskaito išsaugotą pasirinkimą ir, jei toks yra, įrašo jį į šakninio elemento atributą data-theme:
<meta name="color-scheme" content="light dark">
<script>
(function () {
var saved = null;
try { saved = localStorage.getItem('theme'); } catch (e) {}
if (saved === 'light' || saved === 'dark') {
document.documentElement.dataset.theme = saved;
}
})();
</script>try reikalingas todėl, kad privačiame režime arba užblokavus saugyklą naršyklė meta klaidą, ir be jo visas puslapis liktų be temos.2 žingsnis. Aprašykite spalvas vieną kartą #
Kiekvienos temos spalvos yra reikšmių pora funkcijojelight-dark(): pirmoji šviesiai temai, antroji tamsiai. Tinkamą parenka savybė color-scheme:
:root {
color-scheme: light dark;
--bg: light-dark(#ffffff, #14161a);
--text: light-dark(#1b1f24, #e6e8eb);
--card: light-dark(#f3f5f8, #1e2228);
--line: light-dark(#d8dee6, #2c333c);
--accent: light-dark(#1a56db, #7aa7ff);
}
:root[data-theme="light"] { color-scheme: light; }
:root[data-theme="dark"] { color-scheme: dark; }
body { background: var(--bg); color: var(--text); }data-theme nėra, veikia color-scheme: light dark: puslapis perima sistemos temą be jokios JavaScript eilutės. Kai scenarijus įrašo naudotojo pasirinkimą, dvi paskutinės eilutės priverstinai įjungia reikiamą temą.3 žingsnis. Pridėkite mygtuką #
<button id="theme-toggle" type="button" aria-pressed="false"></button>(function () {
var root = document.documentElement;
var button = document.getElementById('theme-toggle');
var names = { dark: 'Dark', light: 'Light' };
function current() {
return root.dataset.theme ||
(matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light');
}
function show() {
var now = current();
button.textContent = names[now];
button.setAttribute('aria-pressed', now === 'dark');
}
button.addEventListener('click', function () {
var next = current() === 'dark' ? 'light' : 'dark';
root.dataset.theme = next;
try { localStorage.setItem('theme', next); } catch (e) {}
show();
});
show();
})();Patikrinkite patys #
Receptą išbandėme naršyklėje puslapyje su lėtu (dviejų sekundžių) scenarijumi prieš pabaigą, kai saugykloje išsaugotas pasirinkimas „tamsi“, o sistemos tema šviesi. Praėjus 0,8 sekundės nuo įkėlimo pradžios: kai scenarijushead dalyje, puslapis jau tamsus, kai scenarijus pabaigoje – baltas ir toks lieka, kol puslapis perskaitomas iki galo. Štai ką žmogus mato tą akimirką:

Patikrinta ir visa kita: be JavaScript puslapis perima sistemos temą, paspaudus mygtuką ir perkrovus pasirinkimas išlieka, o esant 390, 768 ir 1280 taškų pločiui horizontalios slinkties nėra.
Pakartoti galite taip:
- Atidarykite puslapį, paspauskite mygtuką ir pasirinkite tamsią temą.
- Kūrėjo įrankiuose įjunkite tinklo lėtinimą ir perkraukite puslapį: fonas lieka tamsus nuo pirmo kadro.
- Išjunkite JavaScript ir išvalykite saugyklą: puslapis vėl seka sistemos temą.
Dažnos klaidos #
- Scenarijus puslapio pabaigoje. Blyksnis grįžta: pasirinkimas sužinomas per vėlai.
- Nėra
color-schemeant:root. Be jolight-dark()nežino, kurią reikšmę imti. - Nėra
tryaplinklocalStorage. Privačiame režime kai kuriose naršyklėse puslapis sugenda. - Tema tik JavaScript. Be scenarijaus lankytojas neturi tamsios temos, net jei sistemoje ji įjungta. Receptas tai išsprendžia su
color-scheme. - Nepatikrintas kontrastas. Tekstas ir fonas turi duoti bent 4,5 su 1 – tai WCAG AA prieinamumo taisyklė. Patikrinkite abi temas, ne vieną.

Dar niekas nepakomentavo. Būkite pirmi.