Dark mode s CSS custom properties: přístupnost v atraktivní podobě
Dark mode, tmavý režim, night shift — v poslední době často skloňované pojmy, umocněné podporou tmavého režimu v novém iOS 13. Ukážeme si, jak upravit svůj web pro dark mode čistě s pomocí CSS.
Dark mode, tmavý režim, night shift. V posledních měsících často skloňované pojmy v diskusích o tom, jaký dopad má na člověka digitálního zírání do obrazovky, zejména ve večerních hodinách. Všechny nejrozšířenější operační systémy, mobilní i desktopové, tmavý režim nějakým způsobem podporují. Naposledy jej představil Apple s vydáním iOS 13. Černé pozadí se světlým textem tak přestávají být poznávacím znamením serverových administrátorů a seriálových hackerů.
Co je dark mode
Co je dark mode nebo, chcete-li, tmavý režim? Je to jednoduché: jedním nastavením můžete přepnout celé uživatelské rozhraní svého operačního systému ze světlého barevného schématu do tmavého. Některé platformy a aplikace umí mezi režimy přepínat samy na základě denní doby nebo intenzity okolního světla (což třeba autonavigace dělaly již dávno). Cíl je jediný: nedráždit a neunavovat lidské oko agresivním kontrastem světlých barev v tmavém prostředí.
Tmavý režim šetří zrak a v případě OLED displejů dokonce i baterii.
To je důležité zejména v posledních hodinách před ulehnutím ke spánku. I když je pravda, že ještě lepší než koukat do tmavé obrazovky je nekoukat do žádné obrazovky. Jsou i lidé, kteří mají tmavý režim zapnutý trvale. Tmavý režim šetří zrak a v případě OLED displejů dokonce i baterii zařízení, protože OLED technologie u černé barvy — na rozdíl od klasických LED displejů — zcela vypíná podsvícení.
Vlastnosti, nebo proměnné?
CSS custom properties se často říká CSS proměnné. Pro lepší představu to není špatně, ale také to není úplně přesný popis. Na proměnné jsme zvyklí z preprocesorů, kde je využíváme pro sdílenou definici často používaných hodnot, typicky barev, breakpointů nebo typografie. Custom properties se chováním s preprocesorovými proměnnými částečně překrývají, nicméně kromě toho, že jsou v prohlížečích implementované nativně se od nich liší v několika zásadních bodech:
- Jsou součástí kaskády. Stejně jako ostatní CSS vlastnosti mají dopad na aktuální blok deklarací a kaskádou se dle stejného algoritmu propíší na všechny potomky. To umožňuje řešit jinak složité konstrukce jednoduchou modifikací custom properties pro daný kontext nebo breakpoint.
- Jejich hodnoty lze naživo měnit přímo v prohlížeči. Custom properties jsou nativní vlastností CSS a tím pádem změna jejich hodnoty způsobí překreslení stránky v prohlížeči. To je něco, na co jsou preprocesorové proměnné z principu krátké.
- Mají javascriptové API. Stejně jako ostatní vlastnosti v CSSOM lze custom properties JavaScriptem nejen číst, ale také do nich zapisovat. Obdobného chování bychom bez nich dosáhli jedině manipulací selektorů nebo přímo CSS vlastností, často ovšem bez kaskády.
- Nelze je použít pro hodnoty breakpointů. Jsou to CSS vlastnosti a jako vlastnosti je lze použít pouze v deklaracích. Media queries nejsou deklarací, a proto jsou z nich custom properties vyloučeny. Je to škoda, sdílená definice breakpointů by se velice hodila, zde si ale musíme zatím vystačit s preprocesorem.
Chování CSS custom properties podrobně popisuje nebývale čtivá oficiální specifikace.
Zápis
Custom properties se definují v páru klíč: hodnota, kdy je klíč prefixován dvěma spojovníky (--
).
--boxBackground: #f6f6f6;
--boxBorderRadius: 0.25em;
Protože jde o properties, tedy hodnoty, musíme je vždy definovat v nějakém bloku. Tím může být libovolný selektor:
.listOfBoxes {
--boxBackground: #f6f6f6;
--boxBorderRadius: 0.25em;
}
Pro globálně dostupné vlastnosti pak typicky pseudo selektor :root
:
:root {
--boxBackground: #f6f6f6;
--boxBorderRadius: 0.25em;
}
Definované hodnoty pak můžeme použít v deklaracích zavoláním přes funkci var()
:
.box {
background: var(--boxBackground);
border: var(--boxBorderRadius);
}
Velmi zajímavé je právě využití kaskády. Můžeme si připravit konfigurovatelnou komponentu a její chování pak měnit dle kontextu pouze úpravou hodnot custom properties:
:root {
--cardBackground: #fff;
--cardPadding: 1.5rem;
--cardPaddingDense: 1rem;
}
.card {
padding: var(--cardPadding);
background: var(--cardBackground);
}
.card .card {
--cardPadding: var(--cardPaddingDense);
}
Příklad jde sice proti best practices objektového CSS (používá kontextové stylování), to ale s custom properties zatím moc nepočítá, takže si pro zvědavost a názornost dovolíme pravidlo porušit.
Oblastí, kde OOCSS nebude nic namítat, je tvorba tématu UI — to by zahrnovalo vlastní barevné schéma, stíny, poloměry kulatých rohů, škálu hodnot pro odsazování nebo typografii. Téma bychom dosud aplikovali patrně modifikační CSS třídou nebo přetěžujícím stylopisem. S custom properties se přetěžování můžeme zcela vyhnout, a proto se na tvorbu témat výborně hodí. Třeba právě na implementaci tmavého režimu, jak si ukážeme dále.
Podpora v prohlížečích? Výborná
Přestože jde teprve o nějaké dva tři roky starou vlastnost, její rozšíření v prohlížečích je vynikající: k říjnu 2019 je to v Česku i globálně okolo 90 %. V IE a Opeře Mini s custom properties samozřejmě nepochodíme, ale to jsme asi ani nečekali.
Nic tedy nebrání tomu si CSS custom propreties vyzkoušet v praxi. Nejlépe na nějaké nekritické funkcionalitě, jakou je třeba právě nyní populární tmavý režim neboli dark mode.
Dark mode s custom properties
Základní barevnost dokumentu bychom tradičně definovali nějak takto:
body {
color: black;
background-color: white;
}
Nebo častěji s preprocesorem:
body {
color: $page-text-color;
background-color: $page-background-color;
}
S preprocesorovými proměnnými bychom dokázali téma také připravit, museli bychom však téma držet ve vlastním stylopisu, který bychom načítali zvlášť podle situace. Každé téma by ale zbytečně duplikovalo CSS kód a bez užití JavaScriptu bychom se připravili o další výhody custom properties, jako je živé přepínání tématu přímo v prohlížeči.
Aplikujme proto místo toho CSS custom properties:
body {
color: var(--page-text-color);
background-color: var(--page-background-color);
}
Definujeme si hodnoty pro základní, světlý vzhled:
:root {
--page-text-color: black;
--page-background-color: white;
}
Pro tmavý vzhled můžeme barvy jednoduše obrátit, lepší ale bude zvolit méně kontrastní a k očím šetrnější dvojici barev:
:root {
--page-text-color: silver;
--page-background-color: darkslategrey;
}
Témata tedy máme, jak ale mezi nimi přepínat? Možností je třeba ovládání CSS třídou .is-dark-mode
na prvku <html>
, který proměnné přepíše a ty kaskádou propadnou dále do dokumentu. Třídu pak můžeme navázat JavaScriptem na tlačítko umožňující ruční přepínání tmavého režimu: <html>
(bez CSS třídy) definuje základní (světlý) vzhled, zatímco <html class="is-dark-mode">
přepne stránku do tmavého zobrazení.
:root {
--page-text-color: black;
--page-background-color: white;
}
.is-dark-mode {
--page-text-color: silver;
--page-background-color: darkslategray;
}
Otázka je, zda nemůžeme být chytřejší a preferenci tmavého režimu nějak detekovat a stránku přizpůsobovat automaticky. Nebylo by to pro uživatele pohodlnější?
Mocné media features
Jistě že bylo. Dokonce na to máme nástroj. A dokonce jej dávno známe. Media queries ve valné většině případů používáme pro detekci šířky obrazovky a odpovídajícímu přizpůsobení layoutu stránky. min-width
, max-width
a podobné však zdaleka nejsou vším, co lze v media queries použít. Specifikace media queries definuje řadu moc zajímavých media features a ve verzi 5 přidává něco, co se nám právě teď velmi hodí: prefers-color-scheme
. To může nabývat hodnot no-preference
, dark
nebo light
. Takže podle toho, jaký má uživatel nastavený režim ve svém zařízení jsme schopni s čistým CSS přizpůsobit zobrazení naší stránky jeho preferencím. Není to skvělé? Je to skvělé.
Pozor na to, že kompatibilita s prohlížeči není tak široká, jako u CSS custom properties, stále je to však okolo 70 %, což za povšimnutí rozhodně stojí.
Zkombinujeme tedy využití CSS custom properties a media feature prefers-color-scheme
do jednoho mocného kousku kódu:
:root {
--page-text-color: black;
--page-background-color: white;
}
@media (prefers-color-scheme: dark) {
:root {
--page-text-color: silver;
--page-background-color: darkslategray;
}
}
A to je celé kouzlo. Podle systémového nastavení uživatele umíme přizpůsobit zobrazení naší stránky. S typografií, konkrétně velikostí písma, jsme něco podobného dávno uměli (a ve jménu přístupnosti bychom na to neměli zapomínat ani dnes), možnost měnit barvy je však novinka. Přístupnost v atraktivní podobě.
Do budoucna se můžeme těšit na podporu media feature light-level
. Ta by měla umožnit detekci intenzity okolního osvětlení a podle toho autorsky přizpůsobit zobrazení stránky podobně, jako to již dnes umí tmavý režim. Tato vlastnost však zatím není v prohlížečích implementována.
Související odkazy
- A Complete Guide to Dark Mode on the Web (Adhuham, CSS Tricks, 2020)
- Material Design Guidelines: Dark Theme
Další články od autora:
Sdílejte
Líbí se vám článek? Podpořte jej sdílením!
Komentujte
Chcete k článku něco doplnit? Našli jste chybu? Napište e-mail.