Add Dark mode to websites

4 Jul 2020 ⏱️ 4 min
Add Dark mode to websites

I am a huge fan of dark mode — from editors, terminals to websites, I have most of stuff customized for dark mode. Now most of the website and apps support a dark mode.

Dark Mode is ❤️️

One of the typical case is using your mobile and laptops at night and you don’t want lights on — relatable? Yeah, It is such a pain to use light mode in low light scenarios. Now you want to add it to your personal website and side projects too right? Let’s learn how to do that!


Using Media Queries

A new media queryprefers-color-scheme is added in Media Queries 5 specifications. You can simply set your css based on whether the user’s preferred light/dark mode.

Here, I just show a simple example, where I am setting background-color and color property for both the modes.

@media (prefers-color-scheme: dark) {
  html {
    background-color: black;
    color: white;
  }
}

@media (prefers-color-scheme: light) {
  html {
    background-color: white;
    color: black;
  }
}

Drawback

Although this works for most of the browsers like Chrome( ≥76), Safari( ≥12.1) and Firefox(≥67). Just in case you are worried about people still using older versions then you might want to implement some custom CSS and JS way described below.

Also, if you are still using IE, then only God can help you 😛


Using Custom CSS and JS

You probably have seen sites with those toggle button to switch between light and dark modes. That looks cool! Well, we are going to implement the same cool thing 😎

Let’s add a simple div with this toggle. You can use a button or any other element.

Light theme demo

<div class="switch" id="theme-toggle">
  <div class="slider round"></div>
</div>

The code above is only for the toggle. Now, let’s add some css for the light theme.

/* Add this in light_theme.css */
.switch {
  _display_: flex;
  _height_: 36px;
  _position_: relative;
  _width_: 70px;
}

.slider {
  _background-color_: #fff;
  _border_: 1px solid #000;
  _bottom_: 0;
  _cursor_: pointer;
  _left_: 0;
  _position_: absolute;
  _right_: 0;
  _top_: 0;
  _transition_: 0.4s;
}

.slider:before {
  _background-color_: #333;
  _border_: 1px solid #000;
  _bottom_: 3px;
  _content_: "";
  _height_: 26px;
  _left_: 4px;
  _position_: absolute;
  _transition_: 0.4s;
  _width_: 26px;
  _z-index_: 421;
}

.slider.round {
  _border-radius_: 34px;
}

.slider.round:before {
  _border-radius_: 50%;
}

Similarly, let’s add css for the dark theme —

/* Add this in dark_theme.css */
.switch {
  _display_: flex;
  _height_: 36px;
  _position_: relative;
  _width_: 70px;
}

.slider {
  _background-color_: #fff;
  _border_: 1px solid #000;
  _bottom_: 0;
  _cursor_: pointer;
  _left_: 0;
  _position_: absolute;
  _right_: 0;
  _top_: 0;
  _transition_: 0.4s;
}

.slider:before {
  _background-color_: #333;
  _border_: 1px solid #000;
  _bottom_: 3px;
  _content_: "";
  _height_: 26px;
  _right_: 4px;
  _position_: absolute;
  _transition_: 0.4s;
  _width_: 26px;
  _z-index_: 421;
}

.slider.round {
  _border-radius_: 34px;
}

.slider.round:before {
  _border-radius_: 50%;
}

Once, we have this css added. Don’t forget to include them in your html.

/* Include in your html */
<link
  id="theme"
  rel="stylesheet"
  type="text/css"
  href="css/light_theme.css"
/>

We don’t need to add dark_theme.css since we will add it via custom JS.

You should be able to see a working light theme and a toggle. But, the theme doesn’t change!!

Let’s make that toggle work now! Add javascript to load custom css file based on the theme mode selected. We use localstorage to save user preferences for the theme. We don’t want him to click toggle again and again.

document.addEventListener("DOMContentLoaded", () _=>_ {
  _const_ themeStylesheet = document.getElementById("theme");
  _const_ storedTheme = localStorage.getItem("theme");
  if (storedTheme) {
    themeStylesheet.href = storedTheme;
  }
  _const_ themeToggle = document.getElementById("theme-toggle");
  themeToggle.addEventListener("click", () _=>_ {

  // if it's light -> go dark

  if (themeStylesheet.href.includes("light")) {
    themeStylesheet.href = window.location.origin + "/<filepath-to>/dark_theme.css";
  } else {
    // if it's dark -> go light
    themeStylesheet.href = window.location.origin + "/<filepath-to>/light_theme.css";
  }

    // save the preference to localStorage
    localStorage.setItem("theme", themeStylesheet.href);
    reloadCss()
  });
});

I use a reloadCss() to refresh css files without actual page reload. You can also refresh the page with window.location.reload()

Drawback — This method basically iterates over all CSS links.

_function_ reloadCss() {
 _var_ links = document.getElementsByTagName("link");
 for (_var_ cl in links) {
 _var_ link = links[cl];
 if (link.rel === "stylesheet")
 link.href += "";
 }
}

Result

PS: If you use frameworks like React, Vuejs then there are lot more and better ways to implement this.


Resources

Time to add beautiful dark mode to your websites 🚀

Show your implementations in comments 👇

Liked the article? Consider supporting me ☕️


I hope you learned something new. Feel free to suggest improvements ✔️

I share regular updates and resources on Twitter. Let’s connect!

Keep exploring 🔎 Keep learning 🚀

Liked the content? Do support :)

Paypal - Mohit Khare
Buy me a coffee