☰ menu
Pavel Satrapa

CSS – světlý a tmavý režim

Řada stránek podporuje světlý a tmavý režim zobrazení. Uživatel si v prohlížeči může nastavit, jaké variantě dává přednost. Pokud tak neučiní, prohlížeč obvykle respektuje nastavení v operačním systému. Navíc samozřejmě může být přepínač přímo na stránce, aby si uživatel mohl barevný režim jednoduše změnit.

prefers-color-scheme

Základem podpory pro světlý a tmavý režim je mediální dotaz na vlastnost prefers-color-scheme s možnými hodnotami dark a light. Pravidla CSS, která obsahuje, budou použita, jen pokud uživatelův prohlížeč dává přednost danému režimu.

Obvyklé uspořádání je takové, že se nejprve nadefinují univerzální vlastnosti a následně se přepíše to, co se má změnit v tmavém režimu zobrazení. Změny se zpravidla týkají barev, ale pokud potřebujete, můžete změnit cokoli. Čili CSS vypadá zjednodušeně nějak takto:

:root {
    color: black;
    background-color: white;
}

a {
    color: #a00;
}

@media (prefers-color-scheme: dark) {
    :root {
        color: #eee;
        background-color: #222;
    }

    a {
        color: #f88;
    }
}

Je záhodno si ověřit, zda vše funguje, jak má. Člověk bývá občas překvapen, kde všude nastavil nějakou barvu. Pro tyto účely prohlížeče nabízejí v nástrojích pro vývojáře možnost přepnout si preferovaný režim podle potřeby.

Proměnné

Používání proměnných situaci dost zjednoduší. Není třeba přepisovat všechna pravidla, kde se nastavuje nějaká barva. Stačí barvy definovat pomocí proměnných a v tmavém režimu změnit hodnoty proměnných:

:root {
    --b-pozadi: white;
    --b-text: black;
    --b-odkaz: #a00;
    color: var(--b-text);
    background-color: var(--b-pozadi);
}

a {
    color: var(--b-odkaz);
}

a:hover {
    color: var(--b-pozadi);
    background-color: var(--b-odkaz);
}

@media (prefers-color-scheme: dark) {
    :root {
        --b-pozadi: #222;
        --b-text: #eee;
        --b-odkaz: #f88;
    }
}

Je to výrazně přehlednější a změna barvy se automaticky propíše na všechna místa, kde používáte danou proměnnou. Pomocí míchání barev lze univerzálnost tohoto přístupu posunout ještě o kousek dál. Řekněme, že chceme barevně odlišit navštívené odkazy od nenavštívených. To zpravidla znamená udělat je o něco méně nápadnými. Posuneme je tedy směrem k barvě běžného textu:

a:visited {
    color: color-mix(in oklch, var(--b-odkaz) 75%, var(--b-text));
}

Ve světlém režimu je barva textu černá, takže navštívené odkazy budou tmavší. V tmavém režimu je barva textu světle šedá a navštívené odkazy zesvětlí.

color-scheme a light-dark()

Vzhledem k tomu, že světlé a tmavé režimy zobrazení se staly dost populárními, objevily se v CSS nástroje ušité jim přímo na míru: vlastnost color-scheme a funkce light-dark(). Mají smysl jen společně, používat jednu bez druhé nevede k žádným výsledkům.

Vlastnost color-scheme uvádí režimy, které vaše stránka podporuje. Můžete ji použít pro libovolný prvek, ale obvykle se nastavuje pro :root. Podporujete-li oba režimy, bude v CSS:

:root {
    color-scheme: light dark;
}

Funkce light-dark() se používá na místě hodnoty. Obsahuje dvě hodnoty. Ve světlém režimu vrací první z nich, v tmavém tu druhou. To umožňuje obejít se bez @media:

:root {
    color-scheme: light dark;
    --b-pozadi: light-dark(white, #222);
    --b-text: light-dark(black, #eee);
    --b-odkaz: light-dark(#a00, #f88);
    color: var(--b-text);
    background-color: var(--b-pozadi);
}

a {
    color: var(--b-odkaz);
}

a:hover {
    color: var(--b-pozadi);
    background-color: var(--b-odkaz);
}

Při tomto uspořádání ponecháváte volbu režimu na preferencích prohlížeče. Stránka podporuje oba režimy a podle toho, zda prohlížeč dává přednost světlému nebo tmavému, funkce light-dark() vrátí první nebo druhou hodnotu.

Přepínač režimů

K vytvoření vlastního přepínače režimů lze využít to, že obsahuje-li color-scheme jen jednu hodnotu, bude funkce light-dark() vracet jen jí odpovídající variantu. Dole na stránce mám vypínač s identifikátorem darkswitch. Nastavuji, že stránka podporuje jen světlý režim a pokud je vypínač zapnutý, změním to na pouze tmavý režim:

:root {
    color-scheme: light;
}

:root:has(#darkswitch:checked) {
    color-scheme: dark;
}

Díky tomu výsledky funkcí light-dark() závisí na aktuálním stavu vypínače. Je-li vypnutý, vracejí světlou variantu. Jakmile jej zapnete, změní se jejich výsledky na hodnotu pro tmavý režim.

Chcete-li se dozvědět víc, doporučuji článek Come to the light-dark() Side.