Umschaltbarer Dark Mode mit Next.js und Tailwind CSS

Umschaltbarer Dark Mode mit Next.js und Tailwind CSS

#Technische Voraussetzungen

Ihr benötigt eine Installation mit Next.js und Tailwind CSS, hier genügt folgender Befehl:

npx create-next-app -e with-tailwindcss dark-mode-test

In eurer tailwind.config.js setzt ihr den Punkt darkMode: "class". Möglich wäre hier auch darkMode: "media", dadurch würdet ihr aber die Möglichkeit verlieren, den Modus flexibel zu wechseln. Tailwind CSS bietet die Möglichkeit CSS-Klassen mitzugeben, die nur bei aktivierten Dark-Mode greifen. Diese haben den Präfix dark:.

<h1 className="text-black dark:text-white">Überschrift</h1>

Im oben gezeigten Beispiel wird der Text standardmäßig in schwarz dargestellt. Greift nun jedoch der Dark-Mode, so wechselt dieser auf weiß. Diesen Zustand können wir uns zu nutzen machen und einen Button bauen, der eine "dark"-Klasse auf das HMTL anwendet.

#Umsetzung

Wir beginnen mit dem Erstellen einer Datei und nennen diese useDarkMode.js. Füllt diese mit folgenden Code:

import { useEffect, useState } from "react"; export default function useDarkMode() { const [theme, setTheme] = useState( typeof window !== "undefined" ? localStorage.theme : "light" ); const colorTheme = theme === "dark" ? "light" : "dark"; useEffect(() => { const root = window.document.documentElement; root.classList.remove(colorTheme); root.classList.add(theme); if (typeof window !== "undefined") { localStorage.setItem("theme", theme); } }, [theme]); return [colorTheme, setTheme]; }

Eine kurze Erklärung: Wir nutzen die useState Komponente von React um das Theme umzuschalten. Dieser Zustand wird zudem in den localStorage des Browsers geschrieben, damit dieser beim nächsten Besuch der Seite beibehalten wird. Beim umschalten des Dark-Modes wird die Klasse dark oder light in den HTML-Tag geschrieben, diese bestimmt dann über die Farbgebung der Seite.

Damit die User das ganze nun einfach umschalten können, setzen wir noch einen Button auf die Seite. Hierfür habe ich mir eine Component gebaut, mit folgendem Code:

import useDarkMode from "../lib/useDarkMode"; export default function DarkModeToggle() { const [colorTheme, setTheme] = useDarkMode(); return ( <div className="cursor-pointer dark:text-white"> {colorTheme === "light" ? ( <svg onClick={() => setTheme("light")} xmlns="http://www.w3.org/2000/svg" className="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor" > <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9.663 17h4.673M12 3v1m6.364 1.636l-.707.707M21 12h-1M4 12H3m3.343-5.657l-.707-.707m2.828 9.9a5 5 0 117.072 0l-.548.547A3.374 3.374 0 0014 18.469V19a2 2 0 11-4 0v-.531c0-.895-.356-1.754-.988-2.386l-.548-.547z" /> </svg> ) : ( <svg onClick={() => setTheme("dark")} xmlns="http://www.w3.org/2000/svg" className="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor" > <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z" /> </svg> )} </div> ); }

Dieser Knopf macht sich nun den zuvor erstellen Code zu nutzen und toggelt zwischen den Modi. Er wechselt zudem sein Aussehen, sodass man entweder eine Glühlampe oder einen Mond angezeigt bekommt, je nachdem welches Theme gerade aktiv ist.

Das was auch schon! Setzt euch die Component einfach in die Navigation der Seite und schon könnt ihr und eure User ganz einfach zwischen einem 🌙 Dark- und 💡 Light-Mode wechseln.

Dark Mode Demo