Onjsdev

Share


React Dark Mode With Tailwind CSS

React Dark Mode With Tailwind CSS


By onjsdev

Nov 25th, 2023

The combination of React and Tailwind CSS is so popular for building web pages. If you want to add dark mode to your react application with Tailwind CSS, here are steps to accomplish this.

Update Tailwind Config File

The first thing you need to do is to specify that you will switch the modes on your react app adding the class attribute to the HTML tag, therefore set the "class" to the darkMode key in the Tailwind config file, as shown in the following code snippet:

module.exports = {
  mode: "jit",
  content: ["./src/**/*.{js,jsx,ts,tsx}"],
  darkMode: "class",
  theme: {},
  plugins: [],
}

Design Your Components For The Dark Theme

To specify how the design will look in dark mode, you need to add new classes to elements with the dark: prefix. For example, the following code renders a full-screen page with a white background and black text in light mode and a black background with white text in dark mode.

import "./App.css";
import { ToggleTheme } from "./ToogleTheme";

function App() {
  return (
    <div className="min-h-screen bg-white text-black dark:bg-black dark::text-white">
      {/* We will create this component in the next steps */}
      <ToggleTheme />
    </div>
  );
}

export default App;

Create Tailwind Toggle Switch Component

Most likely, you have seen a toggle switch button that allows users to switch between modes. Therefore, in this step, we will create a component for the switcher.

The list of classes for the switch component is quite long. Simply put, we made the default checkbox invisible and created a custom checkbox instead. We then added peer-prefixed classes that respond to the status of the checkbox

import React, { useEffect, useState } from "react";

export function ToggleTheme() {

  // Code will place here to handle theme preference

  return (
    <label className="relative block w-11 h-6">
      <input
        onChange={toggleMode}
        type="checkbox"
        checked={isDark ? true : false}
        className="peer opacity-0"
      />
      <div
        className="absolute cursor-pointer left-0 
      top-0 bottom-0 right-0 bg-gray-200 rounded-3xl 
      before:absolute before:w-6 before:h-6 before:rounded-full 
      before:bg-yellow-200 peer-checked:before:translate-x-6 peer-checked:before:bg-black 
      before:transition-all duration-300"
      ></div>
    </label>
  );
}

Handle User's Theme Preference

Using the onChange event listener for the checkbox input, we will set the theme based on the user's preference by adding the 'dark' or 'light' class to the HTML tag. We will also save the theme choice to local storage to set the theme again when the user reloads the page.

Here is the last version of the ToggleTheme Component with functions to handle theme preference and switch input.

import React, { useEffect, useState } from "react";

export function ToggleTheme() {
  const [isDark, setIsDark] = useState(false);

  function setDark() {
    // Add or Remove Mode to HTML tag 
    document.documentElement.classList.add("dark");
    document.documentElement.classList.remove("light");
    localStorage.setItem("theme", "dark");
    setIsDark(true);
  }

  function setLight() {
    // Add or Remove Mode to HTML tag 
    document.documentElement.classList.add("light");
    document.documentElement.classList.remove("dark");
    localStorage.removeItem("theme");
    setIsDark(false);
  }

  function toggleMode() {
    if (isDark) {
      setLight();
    } else {
      setDark();
    }
  }

  // When the page is loaded or refreshed, check for theme preference
  useEffect(() => {
    if (localStorage.getItem("theme") == "dark") {
      setDark();
    } else {
      setLight();
    }
  }, []);

  return (
    <label className="relative block w-11 h-6">
      <input
        onChange={toggleMode}
        type="checkbox"
        checked={isDark ? true : false}
        className="peer opacity-0"
      />
      <div
        className="absolute cursor-pointer left-0 
      top-0 bottom-0 right-0 bg-gray-200 rounded-3xl 
      before:absolute before:w-6 before:h-6 before:rounded-full 
      before:bg-yellow-200 peer-checked:before:translate-x-6 peer-checked:before:bg-black 
      before:transition-all duration-300"
      ></div>
    </label>
  );
}

Conclusion

That's all. We have showed how to implement dark mode in a react appliation with Tailwind CSS. After completing your dark mode design using classes with dark: prefix, you can test the theme switching using the toggle checkbox.

Thank you for reading.