Cum detectezi Dark Mode?

Cum detectezi Dark Mode?

De mai bine de un an, toate sistemele de operare, indiferent că-s mobile sau nu, au modul întunecat. Iar browserele pot detecta treaba asta. Uite cum poți detecta treaba asta:

<script type="text/javascript">
    function switchSiteColorScheme(scheme){
        localStorage.siteColorScheme = scheme;
        document.documentElement.className = document.documentElement.className.replace(/(color-scheme-is-[^\s]+)/, '');
        document.documentElement.classList.add(`color-scheme-is-${scheme}`);
    }

    function getSiteColorScheme(){
        const colorScheme = localStorage.siteColorScheme;

        if (!colorScheme && window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
            return 'dark';
        }

        return colorScheme || 'light';
    }

    switchSiteColorScheme(getSiteColorScheme())
</script>

Tot codul ăsta trebuie pus în <head> ȘI inline. Motivul pentru care trebuie să fie inline este că nu vrem un flash al temei greșite până se încarcă site-ul, nu? :)

Codul ăsta face două lucruri:

  1. Expune două funcții (getSiteColorScheme, respectiv switchSiteColorScheme) cu ajutorul cărora poți lua/seta modul curent
  2. Setează modul salvat de utilizator sau, dacă este la o primă vizită, detectează modul setat în sistemul de operare.

Și cam asta e tot!

Cu ce mă ajută o clasă pusă pe html?

În CSS poți folosi variabile. Iar variabilele astea țin cont de scope! Altfel spus, poți defini culorile într-un singur loc, la modul:

:root {
  --header-background-color: #fafafa;
  --header-text-color: #444;
}

/* folosim variabilele: */
.header {
  background-color: var(--header-background-color);
  color: var(--header-text-color);
}

După care, dacă avem modul întunecat, ajustăm doar variabilele:

.color-scheme-is-dark {
  --header-background-color: #444;
  --header-text-color: #fafafa;
}

Cum folosesc un buton pentru schimbarea culorii?

Am zis mai sus că expunem două funcții? Ei bine, le folosim pe alea!

Varianta 1: Inline

Cea mai simplă variantă este să pui un atribut onclick inline:

<a href="#" onclick="switchSiteColorScheme('light'); return false">Light mode</a> | <a href="#" onclick="switchSiteColorScheme('dark'); return false">Dark mode</a>

Chiar dacă arată … urâțel, este OK. Dacă este nevoie să refolosești butonul, te regăsești brusc în situația în care vei repeta codul. Și nu vrei asta, nu?

Varianta 2: și mai mult JS!

În primul rând, schimbăm puțin HTML-ul:

<a href="#" data-color-mode-switch="light">Light mode</a> | <a href="#" data-color-mode-switch="dark">Dark mode</a>

Apoi, în JS, adăugăm event-urile. De data asta, codul trebuie pus în footer (sau, cel puțin, după butoanele de care spuneam mai sus):

const colorSchemeSwitcher = document.querySelectorAll('[data-color-mode-switch]');
for(let i = 0; i < colorSchemeSwitcher.length; i++){
  colorSchemeSwitcher[i].addEventListener('click', (e) => {
    switchSiteColorScheme(e.currentTarget.getAttribute('data-color-mode-switch');
    return false;
  });
}

5 Comentarii

Mălin a scris

@Ionuț Staicu: În afară de faptul că totul e bloated cu JS nowadays și că toate meme-urile alea despre cum browsere consumă căcălău de resurse ar trebui să fie despre cum de fapt e JS care consumă căcălău de resurse, totul e roz pe lumea asta. Nici măcar COVID nu mai e ce-a fost, darămite Vama.

Adaugă un comentariurăspuns pentru

Poți adăuga bucăți de cod folosind [code]codul tău aici[/code], [js][/js], [php][/php] etc.

Link-urile în context sunt binevenite. Comentariile fără nume/email valid sunt șterse.
PS: Comentariul NU este editabil.

Acest sit folosește Akismet pentru a reduce spamul. Află cum sunt procesate datele comentariilor tale.

Site-ul blog.iamntz.com utilizează cookie-uri. Continuarea navigării presupune acceptarea lor. Mai multe informații.

windows apple dropbox facebook twitter