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;