DEV Community

Cover image for Add dark mode to your website with just a few lines of code

Add dark mode to your website with just a few lines of code

AlbertoM on February 17, 2020

This article was originally posted on my blog. Head over to inspiredwebdev.com for more articles and tutorials. Check out my JavaScript course on ...
Collapse
 
taufik_nurrohman profile image
Taufik Nurrohman

Another idea: use single theme file and just toggle a global class name…

button.addEventListener('click', () => {
    document.body.classList.toggle('dark');
    localStorage.setItem('theme', document.body.classList.contains('dark') ? 'dark' : 'light');
});

if (localStorage.getItem('theme') === 'dark') {
    document.body.classList.add('dark');
}
Enter fullscreen mode Exit fullscreen mode
/* Light mode */
body {
  background: #fff;
  color: #000;
}

/* Dark mode */
body.dark {
  background: #000;
  color: #fff;
}
Enter fullscreen mode Exit fullscreen mode
Collapse
 
iamarsenibragimov profile image
Arsen Ibragimov

Good one! Thanks!

Collapse
 
albertomontalesi profile image
AlbertoM

Yes you are right, I might add it to the article for completion.

Collapse
 
mx profile image
Maxime Moreau

And even better, define some css variables to change everything in just a few lines of css (variables declaration).

Collapse
 
anjali1102 profile image
Anjali Chauhan

i have more than 1 page whom i want to add dark theme. how to do that?

Collapse
 
anjali1102 profile image
Anjali Chauhan

i have more than 1 page whom i want to add dark theme. how to do that?

Collapse
 
thomasbnt profile image
Thomas Bnt ☕ • Edited

Nice post !
But an error on example :

document.getElementByID

edit to

document.getElementById

And

<button id="theme-toggle">Switch to dark mode<button>

to

<button id="theme-toggle">Switch to dark mode</button>
Collapse
 
albertomontalesi profile image
AlbertoM

Thanks, I've updated the post

Collapse
 
patryktech profile image
Patryk

According to CanIUse.com [prefers-color-scheme] support is at around 78%, leaving out Internet Explorer and Edge (not Edge Chromium).

Correct me if I'm wrong, but I don't believe browser support is enough for this feature to work properly - you also need a way to set your theme preferences in your OS. I think this is only available on Android Q (Android 10), and I am yet to find a way to set this as a preference in KDE. (No clue about OSX, Windows, and iOS, as I don't use them and had no need to research it so far).

I think it's a bit too early to adopt this, as most users will have older phones.

Collapse
 
pavi2410 profile image
Pavitra Golchha

You can always fallback to light theme in case this feature is not supported.

Collapse
 
patryktech profile image
Patryk

Of course. Better yet, do use a toggle, and don't rely on something unreliable :)

Thread Thread
 
naismith profile image
Chris Naismith

Using both is the preferred option. Support in OS/Browsers for prefers-color-scheme will only increase. Which means if you implement now, you will support more users in the future, rather than doing it later.

Secondly, in initial hit of your site, you can set their preferred theme according to their preferred color schema (dark mode on first hit). If you only rely on a toggle, you force users to use the light mode regardless of their preferred setting.

Thread Thread
 
albertomontalesi profile image
AlbertoM

Correct, combining both is the best idea.

Thread Thread
 
patryktech profile image
Patryk

Admittedly, I should have worded this better, as that is what I do. Check for a LocalStorage preference that I set when the user toggles dark mode, and check the schema if the key isn't set.

Collapse
 
moatazabdalmageed profile image
Moataz Mohammady

Awesome I will try it in my website

Collapse
 
albertomontalesi profile image
AlbertoM

Cool, leave us a link when you implement it!

Collapse
 
13point5 profile image
Bharath Sriraam R R

This is really cool but I was wondering if there would be performance issues when using it with React or frameworks like Angular, etc?

Collapse
 
canadianeagle profile image
T

Works perfectly in React. I did this previously on a Gatsby project and it works perfectly with no noticeable performance implications. I'm not sure about Angular, but it should be the same.

Collapse
 
13point5 profile image
Bharath Sriraam R R

Great, thank you!

Collapse
 
supunkavinda profile image
Supun Kavinda

So, why would you prefer this to CSS variables?

Collapse
 
coly010 profile image
Colum Ferry

CSS Variables for one aren't supported in IE11 : caniuse.com/#feat=css-variables

So for enterprise development you need a ponyfill to support this.

Otherwise, you could certainly set up your theme.css to have a set of CSS Variables you reuse in the rest of your CSS files, then dynamically change between light-theme or dark-theme or other custom themes with JS

Collapse
 
albertomontalesi profile image
AlbertoM

Can you elaborate more?

Collapse
 
kuatyw profile image
Kuatyw

My website's default theme is light. O added switch theme button with your code but if i use darkmode when i go another page of website theme is being light and then dark(after 1secons or less) how can i fix it?

Collapse
 
mdrahiem profile image
Rahimuddin

I believe instead of maintaining a whole different css file, can't we do it using a single extra class to body (class="dark")? I believe this approach is simple, isn't it? Just a suggestion :)

Collapse
 
albertomontalesi profile image
AlbertoM

Yes you can, it's a totally viable alternative.

Collapse
 
khophi profile image
KhoPhi

The downside of this method is that your user won't have control over how they want to view your website so I would consider it only if you don't have time or don't want to implement a toggle.

If a user has system-wide dark mode, the chances they'll be okay with their web pages being dark too are high.

As a 100% dark-mode-everything person I am, pages without dark mode irritate me these day.

Collapse
 
albertomontalesi profile image
AlbertoM

Yes, you are right. I just think that giving user's a choice is better.

Collapse
 
saxxyfoxxy profile image
Jennifer M

Interesting method. I already implemented Dark Mode using a cookie and javascript (if cookie is set, insert these rules into a stylesheet) and it works well, even in IE (though you have to do an if/else to not insert certain non-IE rules or an error will stop your page from loading - easy to do for just those rules, though). The user can toggle it on or off using the same button (if it is set, delete the cookie; if it is not set, add the cookie). I also have several other site settings set up this same way (link underline choice for people who are color blind, and background choices).

I found this article when searching for how to set Dark Mode for browser preferences after seeing it as an option in the browser on my new phone. As I have my Dark Mode cookie set to delete after 24 hours (it is more meant for accessibility during a migraine than out of user preference, but of course can also be used as a preference, especially at night), I'm not planning on implementing the browser choice one after reading this article, especially since it would double up on the stylesheets. I'm not sure if one method is better than the other, but since I use the cookie/javascript writing the stylesheets for multiple purposes (and javascript writes my regular background, a random photo background, onto a body::before so it is fixed even on iOS devices), it works best for me. And yes, all the cookies are declared in my Privacy Policy 😝.

Collapse
 
mzaini30 profile image
Zen

Wow. Awesome. I'll try this in my next projects.

Collapse
 
iamarsenibragimov profile image
Arsen Ibragimov

Don’t forget to share results with us!

Collapse
 
itachiuchiha profile image
Itachi Uchiha

Thanks. You may not need any if block using data attributes. I'm not sure. But this is really great article. Thank you.

Collapse
 
corelhas profile image
Carlos Orelhas

Thanks for sharing! I will try this on my next project.

Collapse
 
iamarsenibragimov profile image
Arsen Ibragimov

I want to implement dark mode on my community’s website. I add it to the backlog

Collapse
 
hozefaj profile image
Hozefa

How about using CSS variables? They can be changed via javascript also.

Collapse
 
albertomontalesi profile image
AlbertoM

I think having two different files can save you having unnecessary load styles for a theme you don't use. I guess at the end of the day, both will work just fine.

Collapse
 
coly010 profile image
Colum Ferry

The browser should also cache both CSS so the user may only notice a dip in performance on the first time they switch, whilst their cache lives.

Collapse
 
itsraghz profile image
Raghavan alias Saravanan Muthu

Hey that is really a super, uber cool tip! I had been thinking of this but not really searched further. It is an easy bite for me. Thank you for sharing the insights!!

Collapse
 
diek profile image
diek

Epic guide, thank you!

Collapse
 
albertomontalesi profile image
AlbertoM

Glad you liked it!

Collapse
 
adhamu profile image
Amit Dhamu

I wrote a similar article a few weeks back with React and Gatsby in mind

amitd.co/blog/implementing-dark-mode

Collapse
 
barzi92367868 profile image
Barzi

Thank you Alberto.
I'm going to add a dark mode to my side project tonight :)

Collapse
 
hibritusta profile image
Hibrit Usta

Thank you. Nice article.

Collapse
 
lukastechs profile image
Lukastechs.Com

Hi? I'm stuck at saving user preference; I want to make the effect on a site hosted on blogger? any quick tip?

Collapse
 
danquack profile image
Daniel Quackenbush

Do you find prefers-color-scheme to actually be populated? When I first looked into this, that field was always null.

Collapse
 
albertomontalesi profile image
AlbertoM

It works well on macos Catalina.