Skip to content

Dark Mode ​

En Tailwind CSS contamos con una clase que nos permite cambiar el tema de nuestra página web, esta clase es dark y se puede aplicar a cualquier elemento de nuestra página web.

Activar el modo oscuro ​

Para activar el modo oscuro en nuestra página web, debemos agregar la clase dark a nuestro elemento raíz, en este caso, el elemento html.

html
<html class="dark">
    ...
</html>

Variante de color ​

Para que esto sea lo más fácil posible, Tailwind CSS nos ofrece una variante de color que nos permite cambiar el color de un elemento en modo oscuro, esta variante se llama dark: y se puede aplicar a cualquier clase de color.

html
<div class="bg-gray-100 dark:bg-gray-800">...</div>

Prefers color && LocalStorage ​

utils/darkMode.js

js
// si existe el modo oscuro en el localStorage
// o si el sistema operativo tiene el modo oscuro activado pero no se ha guardado en el localStorage
if (
    localStorage.theme === "dark" ||
    (!("theme" in localStorage) &&
        window.matchMedia("(prefers-color-scheme: dark)").matches)
) {
    // agregamos la clase dark al elemento html
    document.documentElement.classList.add("dark");
    // guardamos el modo oscuro en el localStorage
    localStorage.theme = "dark";
} else {
    // si no existe el modo oscuro en el localStorage
    // o si el sistema operativo tiene el modo oscuro desactivado
    // removemos la clase dark del elemento html
    document.documentElement.classList.remove("dark");
    // guardamos el modo claro en el localStorage
    localStorage.theme = "light";
}

En React ​

jsx
// es importante llamar al script antes que App.jsx
import "./utils/darkMode";

import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
import "./index.css";

ReactDOM.createRoot(document.getElementById("root")).render(
    <React.StrictMode>
        <App />
    </React.StrictMode>
);

Ej: Header.jsx ​

jsx
import { useEffect, useState } from "react";
import IconMoon from "./icons/IconMoon";
import IconSun from "./icons/IconSun";

const initialDarkToggle = document.documentElement.className.includes("dark");

const Header = () => {
    const [darkToggle, setDarkToggle] = useState(initialDarkToggle);

    useEffect(() => {
        if (darkToggle) {
            document.documentElement.classList.add("dark");
            localStorage.theme = "dark";
        } else {
            document.documentElement.classList.remove("dark");
            localStorage.theme = "light";
        }
    }, [darkToggle]);

    return (
        <header className="container mx-auto px-4 pt-8">
            <div className="flex justify-between">
                <h1 className="text-3xl font-semibold uppercase tracking-[0.3em] text-white">
                    Todo
                </h1>
                <button onClick={() => setDarkToggle(!darkToggle)}>
                    {darkToggle ? <IconSun /> : <IconMoon />}
                </button>
            </div>
        </header>
    );
};

export default Header;