Blog.

Umschaltbarer Dark Mode mit Next.js und Tailwind CSS

Post Header Image
Picture of the author
Leon Frommberger
Posted

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 GIF


More Stories

Post Preview Image

Wie ich meinen Blog mit Next.js und GraphQL erstellte

Wenn du darüber nachdenkst deinen eigenen Dev-Blog zu launchen, dann bist du sehr Wahrscheinlich auf das gleiche Problem gestoßen wie ich: Es gibt zu viele Möglichkeiten. Für welche der Unzähligen Techniken ich mich entschieden habe und wie ich diese umgesetzt habe, erfährst du hier.
Picture of the author
Leon Frommberger