Dark Mode mit Next.js/Tailwind CSS
Eine aktualisierte Version dieses Artikels, findest du hier.
#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.