How To Build An Advanced Light/Dark Theme Website!
Tags: webdev, css, html, darkmode
Published: 2023-04-10 21:25:25

## Introduction:

An adult need, on average, 15 minutes of direct exposure to sunlight per day to produce enough vitamin D, but still many people suffer from vitamin D deficiency due to lack of exposure to natural light and only exposure to artificial blue light.

So, our job as web devs is to make sure that even artificial light does not reach them; by adding dark mode to their websites.

Whether for the sake of stylish looks or accessibility, adding a dark mode to any website has become very popular lately, and considerate to the eyes of programmers and content creators who spend all their day in front of a computer screen Today you will learn “How To Build An Advanced Light/Dark Theme website”

You can find all the code used in this article on [codepen](https://codepen.io/ymhaah/pen/poxJVbP) or [github](https://github.com/ymhaah/Dark-mode-template)

![dark mode meme](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xmh5gvp2je3xgiymfs01.jpg)

---

## The easy way:

You can close the article now, as I have collected a set of libraries that will give you easy to-add dark mode but If you were a **real programmer**, I would wait for a detailed explanation of how to do it yourself when you could use a library and get it done in half the time!

- **[Darkmode.Js](https://darkmodejs.learn.uno/)** library uses the CSS [`mix-blend-mode`](https://developer.mozilla.org/en-US/docs/Web/CSS/mix-blend-mode) in order to bring Dark-mode to any of your websites.
- **[Nightly.js](https://github.com/Fcmam5/nightly.js)** A zero-dependency Javascript library for enabling dark/night mode in you UI.
- **[darkmodejs](https://github.com/Assortment/darkmodejs)** Link between system preferences and your site automatically, And yes, there is no longer creativity in names

And don't forget that most of the new components libraries support dark mode out of the box like [bootstrap](https://getbootstrap.com/).


![real programmer meme](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j6t2ub0wav5h61jdkw92.png)

---

## real programmer way:

Let's start with the simplest thing you can do to make your site support dark mode and also follow device preferences, which is to use the [`color-scheme`](https://developer.mozilla.org/en-US/docs/Web/CSS/color-scheme) CSS property

All new browsers have a default style Built into them, for example when you use a form it Comes in a specific shape and color

Also, most browsers have a dark mode version of all the elements, and using and using the `color-scheme` property changes the page to the browser version of the dark mode.

```css
body {
    color-scheme: dark;
}
```
You should not rely too heavily on this feature, as the level of modification that you can do with it is low, and also your site can vary from browser to browser.

![chorom vs firefox dark mode style](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kfu2gp3k1mwdhknrbchl.jpeg)

In fact, there are many details in this simple thing, but if we want to build an Advanced Light/Dark Theme Website we can't just rely on it, if you want more details, I recommend this video: [Light & Dark mode WITHOUT CSS](https://www.youtube.com/watch?v=n3lcjY4Mm00&ab_channel=KevinPowell)

---

![dark mode colors](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7gg8a30cumusi7rbvhev.jpg)
Before you start writing the code, of course, you have to choose the colors in both modes, and since I am not a designer here is some good sources:

- [Material Design Dark theme](https://m2.material.io/design/color/dark-theme.html)
- [Light & Dark Color Modes in Design Systems](https://medium.com/eightshapes-llc/light-dark-9f8ea42c9081)


After you choose the appropriate colors for your project, the easiest way to deal with these colors is to collect them in a system of [CSS variables](https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties):

```css
:root{
    --clr-dark-gray: hsl(0, 0%, 13%);
    --clr-white: hsl(200, 16%, 89%);
}
```

- Create a variable that represents dark mode and light mode [--`bg-clr-light`, `--bg-clr-dark`, ...]

```css
:root{
    /* light mode */
    --bg-clr-light: var(--clr-white);
    --txt-clr-light: var(--clr-dark-gray);
    /* dark mode */
    --bg-clr-dark: var(--clr-dark-gray);
    --txt-clr-dark: var(--clr-white);
}
```

- Create the main variables that are used throughout the site [`--bg-clr`, `--txt-clr`, ...]

- And in the absence of the **'dark'** class make that the value of the main variables is equal to the light mode variables: `--bg-clr: var(--bg-clr-light);` and vice versa

```css
body {
    --bg-clr: var(--bg-clr-light);
    --txt-clr: var(--txt-clr-light);
    color-scheme: light;
}
body.dark{
    --bg-clr: var(--bg-clr-dark);
    --txt-clr: var(--txt-clr-dark);
    color-scheme: dark;
}
```

- Use these variables in your project, as their value will change once you but the 'dark' class

```css
.App {
    background-color: var(--bg-clr);
}
```

## CSS code
```css
:root{
    --clr-dark-gray: hsl(0, 0%, 13%);
    --clr-white: hsl(200, 16%, 89%);

    --bg-clr-light: var(--clr-white);
    --txt-clr-light: var(--clr-dark-gray);

    --bg-clr-dark: var(--clr-dark-gray);
    --txt-clr-dark: var(--clr-white);
}
body {
    --bg-clr: var(--bg-clr-light);
    --txt-clr: var(--txt-clr-light);
    color-scheme: light;
}
body.dark{
    --bg-clr: var(--bg-clr-dark);
    --txt-clr: var(--txt-clr-dark);
    color-scheme: dark;
}
.App {
    background-color: var(--bg-clr);
}
```
all that's left is everyone's favorite part **JS**

![js meme](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c26zlb75boph8tdiw7v8.jpg)
 
Don't worry all you have to do is toggle the 'dark' class on the body when you click on the button.

```js
let toggleButton = document.querySelector(".Button");
let body = document.querySelector("body");

toggleButton.addEventListener("click", () => {
    body.classList.toggle("dark");
});
```

- Target the button and the body using [`document.querySelector(document.querySelector)`](https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector)
- add an **EventListener** to listen to the button when clicked using [`addEventListener(type, listener)`](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener)
- pass a function to the **EventListener** that adds or removes the class to the body using [`classList.toggle(class)`](https://developer.mozilla.org/en-US/docs/Web/API/Element/classList)

And now when you press the button the 'dark' class will be added and the main CSS variables values will be swapped.

Of course, you can make the project more elegant by adding animations, keeping the status of the site, and other ideas, but I leave the opportunity for your creativity to continue here after me.

But I will not leave you without many sources to draw inspiration from them and continue learning more:

- [How To Build An Advanced Light/Dark Theme Toggle](https://www.youtube.com/watch?v=RiWxhm5ZdFM&ab_channel=WebDevSimplified)
- [How to make a website light/dark toggle with CSS & JS](https://www.youtube.com/watch?v=wodWDIdV9BY&ab_channel=KevinPowell)
- [How To Build An Advanced Light/Dark Theme Website!](https://www.youtube.com/watch?v=dQw4w9WgXcQ&ab_channel=RickAstley)

---

## Conclusion:

this was How To Build An Advanced Light/Dark Theme Website, and don't forget to make dark mode the default mode on your website.

In the end, I would like to hear your opinions about the article.

- What was missing?
- Should I add more or fewer details?

I hope you liked the article and don't forget to follow me on:

## Author

- professional links:
    - [Twitter](https://twitter.com/hafanwi)
    - [LinkedIn](https://www.linkedin.com/in/youssef-hafnawy/)
    - [GitHub](https://github.com/ymhaah)
- Hire me:
    - [UpWork](https://www.upwork.com/services/product/development-it-a-custom-and-responsive-websites-in-wordpress-1577236892828233728?ref=project_share)
    - [Freelancer](https://freelancer.com/u/ymhaah)
- Blog:
    - [HashNode](https://hafnawi.hashnode.dev/)
    - [Dev.to](https://dev.to/ymhaah)
    - [Medium](https://medium.com/@ymhaah250)