Jak wdrożyć dark mode automatycznie na mobile

Coraz więcej użytkowników oczekuje intuicyjnych i efektywnych rozwiązań podczas korzystania ze stron na urządzeniach mobilnych. Jednym z kluczowych elementów poprawiających komfort pracy w warunkach słabego oświetlenia jest dark mode. Dzięki automatycznemu wykrywaniu preferencji systemowych i szybkiej zmianie stylu, aplikacja lub strona mobilna może zaoferować spójne i przyjazne doświadczenie bez potrzeby ręcznego przełączania opcji. W poniższym artykule omówimy, jak krok po kroku wdrożyć dark mode na urządzeniach mobilnych, zwracając uwagę na aspekty wydajności, dostępności i dobre praktyki projektowe.

Dlaczego warto wdrożyć automatyczny dark mode?

Coraz więcej systemów operacyjnych mobilnych, takich jak Android i iOS, udostępnia globalne ustawienie trybu nocnego, które użytkownicy mogą wybrać ze względu na:

  • Komfort oczu – ciemne tło redukuje odblaski i zmniejsza zmęczenie przy słabym świetle,
  • Oszczędność energii – na ekranach OLED piksele mogą być całkowicie wygaszane,
  • Estetykę – wielu odbiorców ceni nowoczesny, elegancki wygląd ciemnych interfejsów,
  • Dostępność – osoby wrażliwe na jasne światło zyskują lepszy komfort nawigacji.

Wdrożenie automatycznego mechanizmu wykrywania pozwala spójnie reagować na ustawienia systemowe użytkownika i zwiększa zaangażowanie poprzez eliminację potrzeby ręcznego przełączania motywu.

Wykrywanie preferencji użytkownika

Media Queries w CSS

Najprostszym sposobem na rozpoznanie, czy użytkownik preferuje dark mode, jest użycie media queries w CSS. Wystarczy dodać poniższy fragment do arkusza stylów:

@media (prefers-color-scheme: dark) {
  /* Definicje dla ciemnego motywu */
  body {
    background-color: #121212;
    color: #e0e0e0;
  }
  a {
    color: #bb86fc;
  }
}

Zaletą tej metody jest prostota i brak konieczności dodatkowej logiki po stronie JavaScript. Przeglądarka sama wykrywa ustawienie systemowe i stosuje odpowiednie reguły.

Wykrycie zmian w czasie rzeczywistym za pomocą JavaScript

Aby reagować na dynamiczne zmiany preferencji użytkownika bez odświeżania strony, można wykorzystać interfejs matchMedia:

const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
function updateTheme(e) {
  if (e.matches) {
    document.documentElement.setAttribute('data-theme', 'dark');
  } else {
    document.documentElement.setAttribute('data-theme', 'light');
  }
}
mediaQuery.addEventListener('change', updateTheme);
updateTheme(mediaQuery);

Dzięki temu podejściu można w aplikacji dodać dodatkowe przełączniki lub wewnętrzne ustawienia, które zachowają preferencje nawet po zamknięciu karty.

Implementacja krok po kroku

1. Przygotowanie struktur CSS

W pierwszej kolejności należy przygotować dwa zestawy stylów – dla trybu jasnego i ciemnego. Dobrym wzorcem jest użycie zmiennych CSS:

:root {
  --background-color: #ffffff;
  --text-color: #000000;
  --link-color: #1a0dab;
}
[data-theme='dark'] {
  --background-color: #121212;
  --text-color: #e0e0e0;
  --link-color: #bb86fc;
}
body {
  background-color: var(--background-color);
  color: var(--text-color);
}
a {
  color: var(--link-color);
}

W ten sposób zmiana motywu sprowadza się do modyfikacji atrybutu data-theme w elemencie html lub body.

2. Automatyczne wykrywanie i zapamiętywanie wyboru

Choć pobieranie ustawienia systemowego jest kluczowe, warto również umożliwić użytkownikowi ręczne nadpisanie motywu. W tym celu można skorzystać z lokalnego przechowywania:

function getStoredTheme() {
  return localStorage.getItem('theme');
}
function applyTheme(theme) {
  document.documentElement.setAttribute('data-theme', theme);
  localStorage.setItem('theme', theme);
}
const storedTheme = getStoredTheme();
if (storedTheme) {
  applyTheme(storedTheme);
} else {
  updateTheme(window.matchMedia('(prefers-color-scheme: dark)'));
}

Dodanie prostego przycisku przełączającego motyw (np. switch lub ikona) pozwoli zachować preferencje w kolejnych wizytach.

3. Integracja w aplikacji SPA

W środowisku frameworków takich jak React czy Vue należy zastosować analogiczne podejście, umieszczając logikę w głównych komponentach lub hookach. Przykład dla React:

import { useEffect, useState } from 'react';

function useTheme() {
  const [theme, setTheme] = useState(
    localStorage.getItem('theme') ||
    (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light')
  );

  useEffect(() => {
    document.documentElement.setAttribute('data-theme', theme);
    localStorage.setItem('theme', theme);
  }, [theme]);

  return [theme, setTheme];
}

export default function App() {
  const [theme, setTheme] = useTheme();

  return (
    
  );
}

Dzięki takiemu podejściu integracja z istniejącą architekturą jest bezproblemowa i pozwala na centralne sterowanie motywem.

4. Optymalizacja i testowanie

Aby upewnić się, że dark mode działa poprawnie na różnych urządzeniach, warto przeprowadzić:

  • Testy na fizycznych smartfonach z iOS i Androidem,
  • Emulację w narzędziach deweloperskich Chrome i Safari,
  • Kontrolę kontrastu tekstu z narzędziami do analizy dostępności,
  • Audyt wydajności w zakładce Performance, aby uniknąć opóźnień przy przełączaniu motywu.

Dodatkowo można wykorzystać narzędzia CI/CD do automatycznych testów regresji wizualnej, np. Percy lub Chromatic.

Zalecenia i dobre praktyki

  • Spójność: utrzymuj jednolite kolory i komponenty między trybami, aby uniknąć zaskoczenia użytkownika.
  • Dostępność: dbaj o odpowiedni kontrast, stosując narzędzia WCAG, a także testuj czytanie przy pomocy czytników ekranu.
  • Wydajność: minimalizuj liczbę odświeżeń stylów i unikaj kosztownych operacji DOM podczas przełączania motywu.
  • Fallback: przygotuj domyślne style, które zadziałają w starszych przeglądarkach bez wsparcia prefers-color-scheme.
  • Komunikacja: poinformuj użytkowników o dostępności dark mode i daj im możliwość wyboru.
  • Upgrade: aktualizuj bibliotekę komponentów, aby uwzględniały opcję ciemnego motywu w najnowszych wersjach.