There are different ways to implement dark mode on websites, from the simplest to the most complex, and the approach I show in this short tutorial I consider as the simplest and painless possible, for this we will implement using only HTML, CSS and Javascript.
Two key concepts will be used for implementing dark mode, CSS Variables for colors, and localStorage to store the user's current theme.
CSS Variables
CSS variables work like variables from any other language, where we assign values to it and we can modify it later, for implementation of dark mode we will assign the values of our colors to CSS variables, with that we can modify them later depending on the context.
/*creating a css variable */
--bg-grey-light: #f5f5f5;
/*using the css variable */
background-color: var(--bg-grey-light);
A special feature of CSS variables that makes it a good alternative to implementing dark mode is that all elements that are declared inside the parent element will
inherits them, so we'll define our variables directly in the body
so that all elements within it can inherit them.
localStorage API
For a better user experience, we will use localStorage which will store the user's current theme, that way when the user comes back to the website, their favorite theme will be applied automatically.
// storing the theme on the user's machine
localStorage.setItem('theme', 'dark');
//accessed the user's machine theme
localStorage.getItem('theme');
// dark
Document Structure
Being a very small project, our document will consist of two buttons and two blocks of text, the buttons will have the function of changing the theme and updating the page.
index.html
<body>
<div class="container">
<h1 class="heading">
How to make dark mode with HTML, CSS and Javascript only
</h1>
<div class="buttons">
//button to switch dark/light states
<button id="toggle" class="button">toggle</button>
//button to refresh the page
<button id="refresh" class="button">refresh</button>
</div>
<div class="text-wrapper">
<p class="paragraph">
The United States shall be President of the....
</p>
</div>
<div class="text-wrapper">
<p class="paragraph">
Why, there's hardly enough of me left...
</p>
</div>
</div>
<script src="script.js"></script>
</body>
Defining the colors
Since we are dealing with two different contexts, for each color in the light theme there must be a variant for the dark theme, and the colors have to be defined according to your responsibilities, thus having colors for text, background colors…
Definition of variables
/* Definition of colors */
body {
/* text colors */
--text-white: #ffffff;
--text-dark: #142136;
/* background colors */
--bg-grey-light: #f5f5f5;
--bg-white: #ffffff;
--bg-blue-dark: #142136;
--bg-indigo: #6366f1;
/*
...
*/
}
After defining the variables, we will create a class named .dark
, which will contain the definition of the same variables, but with the value of the colors changed to the dark theme, so when we want to change the context to the dark theme, we just add the .dark
class to the body via javascript
so the variables previously defined will be overwritten by the ones defined in the .dark
class.
Variables for the dark theme
.dark {
--text-white: #e6e6e6;
--text-dark: #ffffff;
--bg-grey-light: #142136;
--bg-white: #22395d;
--bg-blue-dark: #142136;
--bg-indigo: #7577e1;
}
}
note that the --text-dark
variable which had its value: #142136
, was changed to #ffffff
in the context of the dark theme, keeping that in mind, you just need to repeat the same process for all other colors of your code.
How did the final .css
file look like:
style.css
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
/* Definition of colors */
body {
/* text colors */
--text-white: #ffffff;
--text-dark: #142136;
/* background colors */
--bg-grey-light: #f5f5f5;
--bg-white: #ffffff;
--bg-blue-dark: #142136;
--bg-indigo: #6366f1;
font-family: "Inter", sans-serif;
line-height: 1.7;
background-color: var(--bg-grey-light);
}
.dark {
--text-white: #e6e6e6;
--text-dark: #ffffff;
--bg-grey-light: #142136;
--bg-white: #22395d;
--bg-blue-dark: #142136;
--bg-indigo: #7577e1;
}
.container {
max-width: 600px;
margin: 40px auto;
display: flex;
padding: 20px;
flex-direction: column;
}
.text-wrapper {
width: 100%;
padding: 20px;
background-color: var(--bg-white);
margin-bottom: 40px;
border-radius: 10px;
}
.paragraph {
font-size: 16px;
color: var(--text-dark);
}
.heading {
font-size: 40px;
letter-spacing: 1px;
font-weight: 900;
margin-bottom: 40px;
color: var(--text-dark);
}
.buttons {
width: 100%;
display: flex;
justify-content: space-between;
margin-bottom: 40px;
}
.button {
width: 200px;
padding: 5px;
height: 40px;
border: none;
border-radius: 10px;
font-family: inherit;
cursor: pointer;
background-color: var(--bg-indigo);
color: var(--text-white);
font-size: 16px;
font-weight: 400;
text-transform: capitalize;
}
As you can see in the code, no color was used directly, instead we used the previously defined variables.
Changing Theme
To switch the theme, we will use javascript, and the script will first check in localStorage if the previously stored theme is dark and apply it to body
as soon as it loads.
We add an eventListener
to the toggle button so when it is clicked it will remove or add the .dark
class and also change the theme stored in localstorage depending on context.
script.js
const toggle = document.getElementById("toggle");
const refresh = document.getElementById("refresh");
const theme = window.localStorage.getItem("theme");
/* checks if the theme stored in localStorage is dark
if yes apply the dark theme to the body */
if (theme === "dark") document.body.classList.add("dark");
// event listener stops when the change theme button is clicked
toggle.addEventListener("click", () => {
document.body.classList.toggle("dark");
if (theme === "dark") {
window.localStorage.setItem("theme", "light");
} else window.localStorage.setItem("theme", "dark");
});
refresh.addEventListener("click", () => {
window.location.reload();
});
Demo: dark-mode.kelven.dev
Source code: Github Repo
Thank you so much for reading this far, I hope my text somehow helped you.
This is my second article/blog post, so feel free to give your opinion about it, which helps me improve.
Take a look at my Portfolio I have some interesting projects there.
Top comments (4)
"dark mode with every technology on the web only"
NGL that title is a bit funny xD
I'd recommend something with a bit more of a hook to get people to read the article; Dark/Light theme switchers are a very common thing and don't really work well to grab attention.
Another nitpick: Some people (including me) block cookies and other storage by default, so it might be worth adding a check for that so the switcher still works, albeit without persistence.
Android application flatter only 😂
A clever approach to dark theme theme.
Nice article article. 👍
Smart but you should add more color for your theme. It will help for beginning learners. Good job.