DEV Community

Cover image for Dark mode: the "best" way (IMO)
Tim Ming
Tim Ming

Posted on • Updated on

Dark mode: the "best" way (IMO)

This blog post provides you a quick TL;DR for the best way to implement dark mode into your website.

Difficulty: Beginner

So, did I mean by the best?

  • Browser support
  • Performance
  • Simplicity

In my opinion; though, there are supporting facts.

---- Let's jump right into it: ----

There are many ways to implement dark mode:

I'm specifically promoting the data-theme method. Click here if you can't bother about the others.

Why choose data-theme?:

  • amazing browser support.
  • lightweight.
  • clean code.

For other methods:

@media(prefers-color-scheme)

Use @media(prefers-color-scheme) if you're against legacy browsers. Here's why.

Seperate CSS files

Please, for the love of developers - don't use this method. Having seperate CSS files will negatively impact your webpage rendering speed. More CSS files means more HTTP Requests are sent to fetch your files, in which will consequently slow down the rendering process.

classList toggle

Well... if you're experienced, you probably heard of the classList.toggle method. Yeah, it works exactly the same as data-theme. Feel free to use it without guilt.

Code

Now that the explanation's done, let me show you an example.

Codepen Example

HTML

I used pug for my HTML, but incase you don't know what's going on:

<div id="container">
  <div id="theme-text">Hi, I'm light theme</div>
  <div id="theme-switch">Click me to change theme</div>
</div>
Enter fullscreen mode Exit fullscreen mode

CSS

I used SCSS as my preprocessor; worry not, I didn't put any SCSS stuff in here. To access the attributes associated with the element, use square brackets. In this case, data-theme="dark" is to be accessed when its value is "dark".

:root{
  --color-bg:#faf7f0;
  --color-font:#363636;
}

body[data-theme="dark"]{
  --color-bg: #282930;
  --color-font: #b1b3bd;
}

body{
  background-color:var(--color-bg);
  color:var(--color-font);
  font-size:1.5rem;
  transition:.2s background-color,.2s color;
}

#container{
  display:flex;
  align-items: center;
  justify-content: center;
  flex-direction:column;
  margin-top:35vh;
}

#theme-switch{
  border:1px var(--color-font) solid;
  margin-top:1rem;
  padding:1rem;
  border-radius:1rem;
  user-select:none;
  cursor:pointer;
}
Enter fullscreen mode Exit fullscreen mode

You will need to use variables if you want it clean. You can create variables to store any value, with the syntax:
--+name:value
Make sure you create them in :root to prevent scope problems.

JS

This is vanilla javascript. :) Noticed how I used the localStorage.setItem method. This works only for the client browser. If you want it to work for the same user on any client, check out SSP.

const themeText = document.getElementById("theme-text")
const themeSwitch = document.getElementById("theme-switch")
if (window.localStorage.getItem("theme") === "dark"){
  document.body.dataset.theme = "dark";
  themeText.innerHTML = "Hi, I'm dark theme";
}
themeSwitch.addEventListener("click",function(){
  if(document.body.dataset.theme !== "dark"){
    document.body.dataset.theme = "dark"
    themeText.innerHTML = "Hi, I'm dark theme"
    window.localStorage.setItem("theme","dark")
  }else{
    document.body.dataset.theme = "light"
    themeText.innerHTML = "Hi, I'm light theme"
    window.localStorage.setItem("theme","light")
  }
})
Enter fullscreen mode Exit fullscreen mode

The data-theme attribute in body is accessed with dataset.theme in JS.

---------End---------

There you go! This is how you can easily add dark mode without any regrets. Though, remember that this is only a small part of the module - at least let me guide you for the design.

My design

Dark mode design examples

<3

Top comments (6)

Collapse
 
alvaromontoro profile image
Alvaro Montoro

The demo is not working on mobile

Collapse
 
timmingau profile image
Tim Ming

I'm so sorry! May I know which browser are you using?

Collapse
 
alvaromontoro profile image
Alvaro Montoro

Sorry, I should have mentioned it. Im using Brave on Android. But just tested with Chrome on Android and it works fine... Maybe it's just my browser?

Thread Thread
 
timmingau profile image
Tim Ming

I think that might be the case! Though brave on iOS works perfectly... Unfortunately I can't find a way to find support for other browsers... That was my bad!

Collapse
 
srezas profile image
SeyedReza SeyedMohseni

forget about the 1 line js code bla bla bla to turn website into dark mode. using css variables is the best way 👍

Collapse
 
timmingau profile image
Tim Ming • Edited

Its good to squeeze in every drop of performance :)