DEV Community

loading...
Cover image for The Best Way To Dark Mode Your Website In My Opinion.

The Best Way To Dark Mode Your Website In My Opinion.

mohammedfarmaan profile image Mohammed Farmaan. ・Updated on ・3 min read

Dark mode has been there for a while now. From apps to websites, its influence on the people has been really great. It's no wonder why everyone would love to have a switch to dark mode option in their Websites.

Now, you might have seen multiple ways of achieving the Dark mode for your website. Whether it be toggling a simple class to turn the background dark or using the Prefers color scheme to switch depending upon the user's system theme. Well, that's great. But people might not always have devices with support for a system wide dark mode. And also, toggling a class might not help a website with multiple colors. So what's the solution?

Here it is: It's actually pretty simple. The best way to achieve Dark Mode is by changing the entire Style Sheet when the user clicks the button for dark mode or toggles a switch.

This method not only gives you the freedom to style a complete dark version of your website but also helps if there are multiple elements which you want to color accordingly, which otherwise would be difficult to achieve by simply toggling a class. You can also have many other color themes for your website. So how do we do that? Enough of reading! Let's get into the code now.

Example:
Here's our HTML file:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Dark Mode Demo</title>
  <link rel="stylesheet" href="light-mode.css" id="theme" />
</head>

<body>
  <div class="wrapper">
    <h1>Demonstration of Dark Mode by changing the style sheet.</h1>
    <button onclick="switchSheet()">Switch</button>
  </div>
  <script src="script.js"></script>
</body>

</html>
Enter fullscreen mode Exit fullscreen mode

Here's our light-mode.css file:

* {
  font-family: "Segoe UI";
  font-weight: 200;
  box-sizing: border-box;
  padding: 0;
  margin: 0;
}
body {
  transition: 1s;
  -webkit-transition: 1s;
  -moz-transition: 1s;
  -ms-transition: 1s;
  -o-transition: 1s;
}

h1 {
  text-align: center;
}
.wrapper {
  height: 100vh;
  width: 100%;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}
button {
  padding: 8px;
  background-color: #000;
  color: #fff;
  border: none;
  border-radius: 3px;
  font-size: 1em;
  margin-top: 1%;
  outline: none;
}
button:hover {
  background: rgb(45, 50, 102);
  color: rgb(255, 255, 255);
}

Enter fullscreen mode Exit fullscreen mode

Here's the dark-mode.css file:

* {
  font-family: "Segoe UI";
  font-weight: 200;
  box-sizing: border-box;
  padding: 0;
  margin: 0;
}
body {
  background: rgb(29, 29, 29);
  transition: 1s;
  -webkit-transition: 1s;
  -moz-transition: 1s;
  -ms-transition: 1s;
  -o-transition: 1s;
}
.wrapper {
  height: 100vh;
  width: 100%;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}
h1 {
  color: #fff;
  text-align: center;
}

button {
  padding: 8px;
  background-color: rgb(255, 255, 255);
  color: rgb(0, 0, 0);
  border: none;
  border-radius: 3px;
  margin-top: 1%;
  font-size: 1em;
  outline: none;
}
button:hover {
  background: rgb(45, 50, 102);
  color: rgb(255, 255, 255);
}

Enter fullscreen mode Exit fullscreen mode

Finally, here's the JavaScript for it:

function switchSheet() {
  let theme = document.getElementById("theme");

  if (theme.getAttribute("href") == "light-mode.css") {
    theme.href = "dark-mode.css";
  } else {
    theme.href = "light-mode.css";
  }
}
Enter fullscreen mode Exit fullscreen mode

In the above example, when the button is clicked, the function switchSheet() checks for the CSS file using the href attribute by the id we gave to the link tag. If light-mode.css exists, it replaces it with the dark-mode.css file. Else it switches it back to the light-mode.css file. That's it! Now you have the Dark Mode for your website without reloading the page at all. Thanks for reading. Hope it helped you. Have a great day!

Edit: I've changed title from "The best way to Dark Mode your Website." to "The best way to Dark Mode your Website in my opinion." Cause there might be other ways better than this, so in my opinion, this is the best.

Here's the link to repo:

GitHub logo zxcodes / Dark-Mode-For-Web

This example shows how you can achieve dark mode for your website by changing the entire style sheet on a click.

Dark Mode For Web

This example shows how you can achieve dark mode for your website by changing the entire style sheet on a click.

Click the link for live demo.

image image

Link to live demo:
https://mohammed-farmaan.github.io/Dark-Mode-For-Web/

Discussion (42)

pic
Editor guide
Collapse
mattwaler profile image
Matt Waler

There is a lot of duplications in this approach in your CSS. For example, now you might change the font family in one file and forget to update it in another. You could definitely move all of the color-specific CSS into a light.css file, the dark into a dark.css file, and a main.css file that holds layout, fonts, etc.

Although I would strongly recommend just nesting all your color definitions in a .dark-mode or light-mode class, and toggle that class on the body element of the page.

Collapse
mohammedfarmaan profile image
Mohammed Farmaan. Author • Edited

Yeah I know. The other CSS file is basically a copy of the first one with a few things changed. And my main intention was to show the switch of files on a click. Anyways, at the end it still falls down to the dev preference on how to lay things out. And yeah, thanks for pointing things out.πŸ˜‡

Collapse
jumokee profile image
jumokee

I like this solution for one reason: it clicked in my head that tags are part of the DOM just like any other element and you can manipulate it with JS. Thanks! πŸ‘ </p>

Thread Thread
mohammedfarmaan profile image
Mohammed Farmaan. Author

Glad it helped you in someway!πŸ˜‡

Collapse
ctrl_alt_aldr profile image
Christian | πŸ§‘πŸΌβ€πŸ’»

Neat approach, I much prefer the CSS Variables method myself though as it means I don't need to juggle two (or more) colour themed CSS files

Collapse
chiubaca profile image
Alex Chiu

second this, css variables can help reduce a lot of duplication and should therefore scale better.

Collapse
td204 profile image
Terry

Too bad you still need a fallback for IE11.

Collapse
ctrl_alt_aldr profile image
Christian | πŸ§‘πŸΌβ€πŸ’»

Yes, for those that need to support IE11 it's a shame - I personally don't however, so I'm happy going forward with CSS Variables 😊

Thread Thread
richardsprins profile image
Richard S Prins Jr. • Edited

Same, its to the point either IE needs to put in the necessary work to be more compatible with the rest of the world or just deprecated itself altogether. Its been a thorn in every web devs heel for decades now to deal with IE compatibility. Safari has done whats necessary to make things easier, why can't Microsoft. Edge was their answer to this and it made nothing any easier.

Thread Thread
perpetualwar profile image
SrΔ‘an MeΔ‘o • Edited

Devs just need to stop supporting IE altogether. Its ridiculous requirement in 2020 that someone needs IE.

Just let it die.

Collapse
sirajulm profile image
Sirajul Muneer

Even bootstrap 5 is dropping support for IE11. It is time to move on. There is no meaning doing extra work to support an old browser.

Thread Thread
td204 profile image
Terry

Yes, please. But commercially this is not (yet) an option in the real business world.

Thread Thread
sirajulm profile image
Sirajul Muneer

That is were progressive enhancement comes handy. You need not always try to figure out a way for fitting a new feature in an old browser. If the browser dont support it, and if it doesnt add any functional and business value, dont bother providing the same for an old browser. Show website without dark mode in IE.

Thread Thread
opauloh profile image
Paulo Henrique

Totally agree, that is to use sense, and careful choose what you are gonna support or not, not being a religious in every decision

Collapse
mohammedfarmaan profile image
Mohammed Farmaan. Author

Yeah sure. It just depends on the user's preference.😁

Collapse
moopet profile image
Ben Sinclair

Won't this give you a flash of the light theme until the script has loaded on every page?

Collapse
eaich profile image
Eddie • Edited

Ben is mostly correct. The page has to first "disconnect" the current CSS file and then load the second. This will cause a temporary moment when the page doesn't have a CSS file bound to it at all. It will be unnoticeable if the CSS files are small or if all CSS files have been cached locally, but you'll definitely see it if your CSS file is large, if you have multiple CSS files, or if your user's have higher latency.

There may be ways around this including possibly preloading the dark mode CSS.

Collapse
mohammedfarmaan profile image
Mohammed Farmaan. Author

Yes that is true. For larger files, it'll take a while to fully load the other sheet but there might be a work around. As soon as I figure it out, I'll pen that one too. Btw, thanks for the point!

Collapse
mohammedfarmaan profile image
Mohammed Farmaan. Author

No it doesn't. I even tried setting a transition, but it still worked smooth and fine.

Collapse
michaelandreuzza profile image
michael-andreuzza

A hack to cover the flash is to have page transition where you fade the html.

Collapse
michaelandreuzza profile image
michael-andreuzza

Yes it will, as a prove my site

I can't be bothered to change it....maybe soon. πŸ˜…

Collapse
td204 profile image
Terry

If using Javascript, why not simply add a class to the body, e.g. "dark-mode" and apply some basic styling overrides in your existing style sheet? No flashes, no new load#/HTTP requests, simply manageable if using a SCSS preprocessor

Collapse
mohammedfarmaan profile image
Mohammed Farmaan. Author

Yeah we can do that too. But few elements will be left out and will need multiple classes to get dark.

Collapse
ok_ape profile image
Amrit Pandey

Cool Hack.

Collapse
mohammedfarmaan profile image
Mohammed Farmaan. Author

Yeah thanks!πŸ˜‡

Collapse
aybee5 profile image
Ibrahim Abdullahi Aliyu

Cool, but there's a typo instead of
the function swapSheet(), it should be switchSheet() as described in the code

Collapse
mohammedfarmaan profile image
Mohammed Farmaan. Author

Thanks. I didn't notice it. Earlier I used a function with that name for same purpose. So I mistyped it here.πŸ˜…

Collapse
suryadatta profile image
suryadatta

An ever easier way is darkmode.js . Try it out

Collapse
mohammedfarmaan profile image
Collapse
doublepicebs profile image
Doublepicebs

Cool! One of my favorite methods is to set a main.css file, light-vars.css and dark-vars.css . Then use the same way you mentioned above to switch the variables sheet.

Collapse
michaelandreuzza profile image
michael-andreuzza

I am having two style sheets on colorsandfonts.com.

When you click on Light icon is just applying the .night class.

And everything changes go and check it out if you are interested.

Collapse
mohammedfarmaan profile image
Mohammed Farmaan. Author

Yeah it's cool. Well done!

Collapse
michaelandreuzza profile image
michael-andreuzza

Great, I am glad you like it !

Collapse
husseinkizz profile image
Hussein Kizz

Wow! I have bookmarked your site and I wonder how you styled such a nice looking dark mode!

Collapse
slk5611 profile image
Collapse
mohammedfarmaan profile image
Mohammed Farmaan. Author

Thank you!πŸ˜„

Collapse
urielbitton profile image
Uriel Bitton

Good stuff man!

Collapse
mohammedfarmaan profile image
Mohammed Farmaan. Author

Thank you so much!πŸ˜‡β€οΈ

Collapse
devparkk profile image
Collapse
codeperfectplus profile image
CodePerfectPlus

It's really useful.

Collapse
tusharpandey13 profile image
Tushar Pandey

wont work in react, or precompiled static sites like gatsby. This is definitely NOT the best way.

Collapse
littleomie profile image
Omie Onin

The title should be "Another way to Dark Mode your Website." or "In my opinion, the best way to Dark Mode your Website.".