How To Create Dark Mode using React & TailwindCSS

How To Create Dark Mode using React & TailwindCSS

Does anyone get furious when they visit a page and it does not have a dark mode feature? Modern web pages give users the flexibility of toggling between light mode and dark mode, which makes it very important for Front-end Developers to implement this feature using the best practices. The ability to toggle the dark mode on and off enhances readability for users across different periods. So in this tutorial, I will be teaching you just how to do that. Let's get into it, shall we?

Prerequisite

To properly understand this article, you need a basic knowledge of :

  • HTML

  • CSS

  • JavaScript

  • React

  • Tailwind CSS

Scaffolding a New React Project

To create a React project, you need Node.js installed on your local machine. If you haven't, you can download it here. I'll be using Vite as a build tool for this project, which I highly recommend as it is fast and gives a very optimized build. You can read more about Vite and all of its interesting features here. Now let's get to real business!

To create a new React project using Vite, run the line of code below in your terminal.

npm create vite@latest

Alternatively, you can directly specify the name of the project(in our project, "dark-mode-project" before runtime as shown below.

npm create vite@latest dark-mode-project --template react

This should install all the necessary packages needed for the development of a new React project.

Adding Tailwind CSS to our Project

To add Tailwind CSS to our Vite project run the following line of code.

npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p

After this, configure your template paths in your tailwind.config.js file which is among the packages that have been added to our project.

// configure your template paths
export default {
  content: [
    "./index.html",
    "./src/**/*.{js,ts,jsx,tsx}",
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}

Then add the tailwind directive to your root index.css file

@tailwind base;
@tailwind components;
@tailwind utilities;

Now we're all set with all the groundwork! Let's run our build command.

npm run dev

Logic: Light/Dark Mode Icon

Just a quick explanation of the logic behind our code here. Two icons will be used, one of which will be visible when we have our light mode functionality, and the other when we have our dark mode functionality. Now that we have an idea of the logic, let's see how we can translate it to code.

We have this icon for light mode

light-mode icon

and this is for dark mode

dark-mode offer

Now let's see how this works.

Implementation

Let's create a simple webpage that we would be utilizing in showing that our logic works. Here's a simple code snippet that shows a text and our Light/Dark mode icon.

import React from "react";
import LightMode from "./light-mode.jpg"
import DarkMode from "./dark-mode.jpg"
import "./index.css";

function App() {
  return (
   <div classname="App">
     <div classname="bg-purple flex flex-end">
     <div className="pl-4 cursor-pointer ">
           <img src={LightMode} />
      </div>
        <div className="flex flex-col justify-center items-center h-full  ">
        <div>
              <h1 className="text-center text-7xl">Our Dark Mode Project</h1>
        </div>
    </div>
    </div>
  );
}

export default App;

The output looks like this :

screenshot of home page

The idea is that when we click on our icon, three events are triggered.

  1. The light mode icon changes to the dark mode icon.

  2. The background colour changes to black.

  3. The text colour changes to white(for visibility and easy readability by users).

Let's implement the functionality for these events one after the other.

Icon change

When we click on our light mode icon, we want it to change to the dark mode icon(which we imported earlier). A simple toggle can be used to implement that. A useState hook is used, as shown below

import React from "react";
import LightMode from "./light-mode.jpg"
import DarkMode from "./dark-mode.jpg"
import "./index.css";

function App() {
 //Toggle function using useState hook
  const [darkMode, setDarkMode] = useState(0);
  const toggleDarkMode = () => {
    setDarkMode(!darkMode);
  }; 

 return (
    <div classname="App">
    <div classname="bg-purple flex flex-end">
     <div className="pl-4 cursor-pointer ">
      {darkMode ? (       
        <img src={LightMode} onClick={toggleDarkMode} />
        ): (
        <img src={DarkMode}  onClick={toggleDarkMode} />
        )}
      </div>
        <div className="flex flex-col justify-center items-center h-full  ">
        <div>
              <h1 className="text-center text-7xl">Our Dark Mode Project</h1>
        </div>
    </div>
    </div>
  );
}

export default App;

This handles the icon change by rendering the light mode icon when Darkmode is false(or 0, as shown in our useState argument), and renders the dark mode icon when Darkmode is true. Darkmode becomes true when it is toggled on, and this is done by the toggleDarkMode function which is triggered when the Light/Dark icon is clicked.

Background Colour Change

This can be easily done by adding some lines of code in Tailwind CSS. It conditionally renders the dark class based on the current state of our Darkmode function.

import React from "react";
import LightMode from "./light-mode.jpg"
import DarkMode from "./dark-mode.jpg"
import "./index.css";


function App() {
 //Toggle function using useState hook
  const [darkMode, setDarkMode] = useState(0);
  const toggleDarkMode = () => {
    setDarkMode(!darkMode);
  }; 

 return (
   <div
      className={`App
    ${darkMode && "dark"}`} 
    >
     <div classname="bg-purple flex flex-end">
     <div className="pl-4 cursor-pointer ">
      {darkMode ? (       
        <img src={LightMode} onClick={toggleDarkMode} />
        ): (
        <img src={DarkMode} onClick={toggleDarkMode} />
        )}
      </div>
        <div className="flex flex-col justify-center items-center h-full  ">
        <div>
              <h1 className="text-center text-7xl">Our Dark Mode Project</h1>
        </div>
    </div>
</div>
  );
}

export default App;

From this code, we see that the dark class is rendered only if DarkMode is set to true, otherwise, it renders the previously existing style. Now let's add the styles when DarkMode is set to true.

We can do this by adding the styles in our index.css file using Tailwind CSS @apply directive.

.dark div {
  @apply bg-black;
}

With this simple snippet of code in our index.css file, whenever our dark class is injected into our Document Object Model(DOM), the background of our webpage changes to black, which is exactly what we want to achieve.

Text Color Change

Since our background colour has been set to black, we would want the colour of our text to be visible, so white colour sounds ideal, and it's easy to include that in our index.css file.

.dark h1 {
  @apply text-white;
}

This changes all instances of the header tag h1 from black to white.

Final Output

Now that we have accomplished all the necessary events for our dark mode functionality. It should look like this.

Toggle Off

screenshot of final output-light mode

Toggle On

screenshot of final output-night mode

And we're all set! Exciting, isn't it?

Conclusion

And that's the end of this piece. I hope you found this helpful. Will write subsequent articles on amazing React and Tailwind features as I am a great fan of both tools. But before then, have fun with this dark mode feature, feel free to explore, and add a couple of events to be affected by the state change. Thanks for reading and I'll see you in the next one!