Dark/Light theme switcher with HTML, CSS & Javascript Only
Tags: html, css, javascript, beginners
Published: 2021-08-29 09:52:46


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.
```css
/*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.
```javascript
// 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
```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
```css
/* 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
```css
.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
```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
```javascript
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](https://dark-mode.kelven.dev)
Source code: [Github Repo](https://github.com/Rubalaine/howto-dark-mode)

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](https://kelven.dev) I have some interesting projects there.