Dark mode is a necessary feature in a modern website. It not only makes the site look cool, but gives the audience an option to feel comfortable too.
In this tutorial we are going to build a simple web page with the option to switch between dark and light color theme. It'll require very basic knowledge of JavaScript and DOM. If you don't know JavaScript, don't fret. It's only one line of code and I'll clarify how that works. Take a look at the end result.
This project is a part of my JavaScript mega project.
Let's start building โ๏ธ
HTML
In our design we'll have a simple layout. It'll contain a header
, article
and footer
. The header
will contain a logo and a button for toggling modes. The article
will have a headline and a link. Let's write the code inside the body.
<header>
<h2>
Logo
</h2>
<button id="toggle">
๐
</button>
</header>
<article>
<h1>
Toggle dark mode with one line of JavaScript ๐
</h1>
<a href="#">
Tutorial
</a>
</article>
<footer>
<p>
Copyright @ 2020
</p>
</footer>
Now set a function to the button, that will run/ called when it is clicked. We'll write the JavaScript function later. Name the function mode
.
<button id="toggle" onclick="mode()">
๐
</button>
CSS
First set up some global styling to our page. I've imported a font from Google Fonts, set the color
, background-color
and transition
for the body
.
@import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@300;500&display=swap');
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
width: 100%;
height: 100vh;
font-family: 'Montserrat', sans-serif;
background: #eeeeee;
color: #333333;
transition: all 0.5s ease-in;
}
For the layout we'll separate those three parts with vh
unit values.
header {
height: 25vh;
}
article {
height: 60vh;
}
footer {
height: 15vh;
}
Now let's add the styling to the skeleton. For the header
, we'll place the child elements on oppsite direction of each other. For the article
and footer
, we'll place the child elements in the center of their parent elements.
header {
display: flex;
justify-content: space-between;
align-items: center;
}
article,
footer {
display: grid;
gap: 15px;
justify-items: center;
align-content: center;
text-align: center;
}
If you notice you'll see that the child elements of the header
are like touching the walls and the button's font-size is small. Let's fix this. Also make the link a bit nicer.
body > * {
padding: 0 15px;
}
a {
text-decoration: none;
font-size: 20px;
color: #ffffff;
padding: 10px 25px;
background: teal;
border-radius: 25px;
transition: all 0.5s ease-in;
}
#toggle {
cursor: pointer
font-size: 25px;
}
Now let's create a CSS class selector and add our dark color scheme inside that class. Later via JavaScript, we'll add that class selector to the body
and toggle between modes. So the color
and the background-color
of the body
will change.
.dark {
color: #ffffff;
background: #333333;
}
.dark a {
background: #37d796;
}
Our basic CSS is done here.
JavaScript
Since we added onclick
on the button, we'll just create the function here. It's only one line so I'll add it inside my HTML page.
<script type="text/javascript" charset="utf-8">
const mode = () => document.body.classList.toggle('dark');
</script>
I've used arrow function
in my example for one line's sake, but any regular function will work the same. Like this:
function mode(){
document.body.classList.toggle('dark');
}
Let me explain the code to you. In the HTML we set a click event. We literally said that if the button is clicked, run the mode
function.
In our JavaScript we created the mode
function. Inside the function we located the body
element by document.body
. Then we used the classList API
. It'll return a class to the body
element.
After that, we used toggle('dark')
.
toggle
will toggle/ switch the class in the body
. More clearly, if the body
doesn't have the class, it'll add that class. If the element has the class, it'll remove that class.
Changing the toggle icon
There are several way to change the icon but we're going to use the simplest way. We'll use the ::before
pseudo selector to achieve that. So our button won't have an icon of it's own but it's pseudo selector's. On toggle we'll change that by using any emoji inside the content: ' '
.
Edit HTML
<button id="toggle" onclick="mode()">
<!-- ๐
changed in css -->
</button>
And CSS
#toggle {
cursor: pointer;
font-size: 25px;
width: 50px;
height: 50px;
border: 0;
background: transparent;
position: relative;
}
#toggle::before {
content: '๐
';
}
.dark #toggle::before {
content: '๐';
}
Congrats! You've made it. let me know your thoughts. If you think you need the source code, here's the link.
Considerations
The button has accessibility issues since there's no text. Try to use
aria-label
or add.sr-only
.Emojis look different based on the system or app. So try to use alternative, like SVG icons.
transition
property doesn't work on CSS gradient backgrounds. But you can make that work by using a simple technique. Here is a tutorial for this.
Thanks for reading this far. I regularly update my learning in Twitter. Feel free to connect.
Cover image is brought from Unsplash.