6

How to Create Dark/Light Mode with React (Tailwind Styling)

 1 year ago
source link: https://dev.to/naomipham_/how-to-create-darklight-mode-with-react-and-tailwind-59e0
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

As developers, we should not limit ourselves to just one thing. Let’s make our app more dynamic with both dark & light versions.

There are many tutorials about toggling Dark/Light mode with ReactJS. Here’s my simple solution using React hook and CSS classes. I hope it will be useful for your project.


Install React & Tailwind

The first step is to install Tailwind for React app. If you haven’t already, follow steps below to set it up:


Install React

# Create a React site

npm create vite@latest my-blog --template-react

I use Vite for React set-up, but you can use any other build tool like Create-react-app.

Select framework React and variant JavaScript.

# Install React dependency

cd my-blog
npm install

# Start dev server

npm run dev

Install Tailwind

# Install Tailwind in your app

npm install -D tailwindcss postcss autoprefixer

# Create tailwind.config.js and postcss.config.js files

npx tailwindcss init -p

# Add paths to all template files in tailwind.config.js

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

# Import Tailwind to CSS - Add this code to start of your ./src/index.css file

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

👉 Official tutorial by Tailwind here

Now run npm run dev to see your site in a web browser.


Set up basic layout

If you look into src folder of your app, you will see there are two jsx files already set up: main.jsx and App.jsx.

Basically, App.jsx contains your components for the app (Navbar, Header, MainBody, Footer, etc.) while main.jsx is responsible for displaying App.jsx on the server. Components of your app usually lie within the components folder.

Vite does not give us a default components folder. So let’s create one .src/components and add a Nav.jsx file:

import React from "react";

export default function Nav() {
    return (
        <nav>
            <h1>hello world</h1>
        </nav>
    )
}

We will add more code to this later. For now, just put a temporary <h1> to see how it’s rendered in the app.

To display Nav content, import Nav.jsx to App.jsx:

import Nav from "./components/Nav"

export default function App() {
    return {
    <Nav />
}}

Now we can work on the dark/light mode.


Set up Dark/Light mode for React

Here are five steps we'll go through to set up Dark/Light Theme for React app:


Step 1: Set darkMode State

const [darkMode, setDarkMode] = React.useState(true)

darkMode will be set to intial true boolean value. This means that by default the site will be dark theme. If you want the default theme to be light, use false instead.

👉 If you like to refresh your knowledge on state & props, check out this article by Ahmed.


Step 2: Create toggleDarkMode function

function toggleDarkMode() {
        setDarkMode(prevDarkMode => !prevDarkMode)
    }

When toggleDarkMode is triggered, darkMode state will alternate between true and false.


Step 3: Trigger toggleDarkMode function

To trigger toggleDarkMode, you need to use onClick handler. This handler will be placed where the user clicks to toggle dark/light mode.

For this app, I will place the handler in the toggle-icon inside Nav component.

Here's my set up for Nav.jsx with a simple h4 and toggle-icon image:

import React from "react";

export default function Nav(props) {
    return (
        <nav 
            className="grid grid-cols-2 w-full place-content-between items-center"
    >
            <h4>Home</h4>
            <img src="./src/assets/toggle-icon-dark.svg" />
        </nav>
    )
}

It looks something like this on the server:

Dark-navbar

The idea is that when darkMode is set to true, the image will be toggle-icon-dark.svg. When darkMode is false, the image will be toggle-icon-light.svg.

Light-navbar

But before changing the images, let's go back to App.jsx file and set up a few things.

Inside Nav element in App.jsx, add the keys darkMode & toggleDarkMode:

<Nav 
    darkMode={darkMode} 
    toggleDarkMode={toggleDarkMode} 
/>

The first key will watch whether darkMode is true or not, while the second key will control the toggle.

When the toggle-icon is clicked, darkMode will be set either true or false. True will render the page in dark theme and false will render the page in light theme.

In step 1, we've set the darkMode state in the parent file App.jsx. To pass it on to the child file Nav.js, we have to use props.

First, add onclick to the toggle icon image in Nav.js:

import React from "react";

export default function Nav(props) {
    return (
        <nav className="grid grid-cols-2 place-content-between items-center w-full">
            <h4>home</h4>
            <img onClick={props.toggleDarkMode} 
                 className="self-left justify-self-end" 
                 src="./src/assets/toggle-icon-light.svg" />
        </nav>
    )
}

Next use the tenary operator to toggle the images based on the dark/light mode:

src={props.darkMode ? "./src/assets/toggle-icon-dark.svg" : "./src/assets/toggle-icon-dark.svg"} 

When props.darkMode is true, the icon image will be toggle-icon-dark.svg . If darkMode is false, it will set to toggle-icon-light.svg. As you click on toggle-icon image, toggle-icon-dark.svg and toggle-icon-light.svg will alternate due to the state we have set early on.

💡 Ternary operator is great when you need to choose between two options in React. When you want to render something on the page, try && conditional rendering.


Step 4: Create CSS classes for dark & light modes

So we’ve got the toggle working (toggle between true/false and icon image light/dark onClick).

Though if you take a look at the server, everything will look the same except the toggle image. That's because we haven't actually change the background and text-color when the mode changes.

There are many ways to toggle dark/light background and text color in Tailwind. For this example, I will create dark & light classes in plain CSS.

Here’s my code in CSS:

:root {
  --clr-bg-dark: #1f2937; /* gray-800 */
  --clr-bg-light: #e2e8f0; /* slate-200 */

  --clr-text-dark: #e2e8f0; /* slate-200 */
  --clr-text-light: #1e293b; /* slate-800 */
}

.dark {
  background-color: var(--clr-bg-dark);
  color: var(--clr-text-dark);
}

.light {
  background-color: var(--clr-bg-light);
  color: var(--clr-text-light);
}

Step 5: Change background-color & text-color according to dark & light modes

Now you need to add dark/light classes depending the mode your site is on.

Return to App.jsx and add these lines of code inside the return:

return (
    <div className={`h-full w-full mx-auto py-2 
                    ${darkMode ? "dark" : "light"}`}
    >
    <Nav 
        darkMode={darkMode} 
        toggleDarkMode={toggleDarkMode} 
    />
    </div>
)

The outer wrap <div> will set the background and text-color for the entire page. We set height and width to full so that it will cover the whole body.

Again, you can use tenary operator to toggle between two options. If darkMode is true, dark class will be added. Otherwise, light class will be added. dark and light classes will alternate based on the state of darkMode.


⚡ Example of Dark/Light Mode in a React site:

Page-dark

Page-light

How do you set up Dark/Light mode in ReactJS? Let’s me know! I'm easily reachable on Twitter


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK