Initial Set up
First Lets set up our initial Project.
git clone https://github.com/hyeo151/Darkmode-Tutorial-React-Tailwind.git
cd Darkmode-Tutorial-React-Tailwind
npm install
npm run dev
When you start your server,you will either see light mode or dark mode depending on your OS color preference.
By default tailwind uses
prefers-color-scheme
CSS media feature to enable Dark mode.
Class Strategy Set up
If we wish to add Dark mode which can be toggled by a user we can use class strategy
Go to tailwind.config.js and add darkMode: 'class'
/** @type {import('tailwindcss').Config} */
export default {
content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx}"],
darkMode: 'class',
theme: {
extend: {},
},
plugins: [],
};
Now we can add darkmode by simply adding class="dark"
in our html element in index.html
like this,
enables dark mode
<html lang="en" class="dark">
disable dark mode
<html lang="en" class="">
Dark Mode Logic
Now that we have set up class Strategy in our project let's add our logic for dark mode.
First we will add following script in our index.html
in head element
. Add this script before any other scripts or links.
<script>
const initialTheme =
localStorage.theme === "dark" ||
(!("theme" in localStorage) &&
window.matchMedia("(prefers-color-scheme: dark)").matches);
if (initialTheme) {
window.document.documentElement.classList.add("dark");
}
</script>
Script like this is called Render-blocking resources which prevents a web page from loading quickly. However we use this method as opposed to using useEffect hook to avoid flashing
This Script instruct following,
[if local storage theme variable is dark]
OR
[if theme variable doesn't exist in local storage AND OS preference is dark]
THEN set our page as dark mode.
This script will load correct mode on initial page load.
Now Let's add darkTheme state for our project.
Go to App.jsx
and declare darkTheme state.
We can use initialTheme that we declared previously and use it as our initial state.
const [darkTheme, setDarkTheme] = useState(initialTheme);
and we show icon according to our darkTheme state
{darkTheme ? (
<i className="fa-solid fa-sun"></i>
) : (
<i className="fa-regular fa-moon"></i>
)}
then we add clicked button which to toggle this state.
onClick={() => {
handleThemeSwitch(setDarkTheme);
}}
Define function handleThemeSwitch
const handleThemeSwitch = (setDarkTheme) => {
if (document.documentElement.classList.contains("dark")) {
document.documentElement.classList.remove("dark");
localStorage.theme = "light";
setDarkTheme(false);
return;
}
localStorage.theme = "dark";
document.documentElement.classList.add("dark");
setDarkTheme(true);
};
Final Code will look like this,
import { useState } from "react";
import "./App.css";
const handleThemeSwitch = (setDarkTheme) => {
if (document.documentElement.classList.contains("dark")) {
document.documentElement.classList.remove("dark");
localStorage.theme = "light";
setDarkTheme(false);
return;
}
localStorage.theme = "dark";
document.documentElement.classList.add("dark");
setDarkTheme(true);
};
function App() {
const [darkTheme, setDarkTheme] = useState(initialTheme);
return (
<div className="max-w-md rounded-md bg-slate-200 p-5 dark:bg-slate-300/80">
<h1 className="mb-2 text-xl font-bold">Tailwind Dark/Light Mode</h1>
<p className="mb-4">
In this tutorial we will be learning how to enable dark mode for your
tailwind react website/app
</p>
<button
className="rounded-md bg-slate-500 px-5 py-1 font-bold"
onClick={() => {
handleThemeSwitch(setDarkTheme);
}}
>
<div className="moon">
{darkTheme ? (
<i className="fa-solid fa-sun"></i>
) : (
<i className="fa-regular fa-moon"></i>
)}
</div>
</button>
</div>
);
}
export default App;
Now whenever user click on the switch button we can switch the dark mode.
If you get stuck you can check out the solution branch
git checkout solution
Thank you for reading!
If you liked this post please like, comment and share.
Ask questions in comment section : )
Top comments (0)