These days everyone needs a dark mode feature in their app. Why? Well, people love using stuff that doesn't hurt their eyes and can be used discreetly (Yeah, I'm looking at you night owls)
Now a question would be, why not make it dark from the very start?
So the answer would be that there are people who feel it inconvenient to use dark mode, so an accessibility issue arises.
So I was working on building three different apps and decided that I should keep the dark mode toggle too.
Header
Usually, the toggle is placed in the header. Thus, we will create a React component that will hold the button for switching the themes.
Using the React hooks, useState, and useEffect, we make the state and the side effect that will add/remove the class for the dark mode.
function Header() {
const [ darkMode, setDarkMode ] = React.useState(false)
React.useEffect(() => {
const body = document.body
const toggle = document.querySelector('.toggle-inner')
// If dark mode is enabled - adds classes to update dark-mode styling.
// Else, removes and styling is as normal.
if( darkMode === true ) {
body.classList.add('dark-mode')
toggle.classList.add('toggle-active')
} else {
body.classList.remove('dark-mode')
toggle.classList.remove('toggle-active')
}
}, [darkMode])
return (
<header>
<div
id="toggle"
onClick={() => darkMode === false ? setDarkMode(true) : setDarkMode(false)}
>
<div className="toggle-inner"/>
</div>
</header>
)
}
App
Just to create a little content for the page, I have added some text.
We are importing the Header component.
function App() {
return (
<main>
<Header />
<div id="container">
<h1>React Dark Mode</h1>
<p>Uses state to set a class on the body if dark mode is enabled.</p>
<p>Implementation is done due to a side effect</p>
</div>
</main>
)
}
ReactDOM.render(
<App />,
document.getElementById('app')
)
CSS
After we are done with the components, we need to style it a bit.
The basic setup is something just removing the margin and padding and the total width and height of an element as box-sizing.
*,
*:before,
*:after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
Then we go on and give a basic background, height, and width to our page.
body {
color: #1a202c;
transition: color 0.2s ease-in;
}
#app {
height: 100vh;
width: 100%;
}
After that, we need to style the main section and the header.
An interesting addition is the transition property. This provides a smooth change to the background color. And we add position: absolute;
in the header so that we can overlap over other elements.
main {
background-color: #f7fafc;
height: 100%;
width: 100%;
padding: 20px;
transition: background-color 0.2s ease-in;
}
header {
position: absolute;
right: 2rem;
}
Then the container containing the little text that we have written is styled. Nothing too fancy, we just center it to the window and apply a few color variations to the headings and paragraphs
#container {
display: flex;
height: 100%;
width: 100%;
align-items: center;
justify-content: center;
flex-direction: column;
}
#container h1 {
padding: 0;
margin: 0 0 10px 0;
}
#container p {
opacity: 0.8;
}
After we are done with this, 60% is done. All we need to do is implement the styles for the toggle and dark mode variations.
Let's jump into the toggle then:
#toggle {
width: 50px;
display: flex;
padding: 5px;
background-color: #1a202c;
border-radius: 1000px;
cursor: pointer;
box-shadow: 0px 5px 20px -10px #000;
transition: background-color 0.2s ease-in;
}
#toggle .toggle-inner {
width: 20px;
height: 15px;
background-color: white;
border-radius: 1000px;
transition: margin-left 0.2s ease-in, background-color 0.2s ease-in;
}
#toggle .toggle-active {
margin-left: 20px;
}
Finally, the dark mode styling is done something like below. We just change the background colors and the text color. That's all
.dark-mode {
color: white;
}
.dark-mode main {
background-color: #1a202c;
}
.dark-mode #toggle {
background-color: white;
}
.dark-mode #toggle .toggle-inner {
background-color: #1a202c;
}
So that's it. It'll be a big help for your next project, the same as it was for me. I don't have to keep checking different pens for the same thing now xD.
Customize it and have fun!
Top comments (0)