DEV Community

Cover image for Implement Dark Mode On Your Website.
Matthew Marquise
Matthew Marquise

Posted on • Updated on

Implement Dark Mode On Your Website.

Dark Mode is an extremely popular feature to implement into your website using basic HTML, CSS and JS. So why don't you have it on yours yet? In three easy steps you can enhance your site to incorporate dark mode! Let's get started.

Table Of Contents

Step 1
Step 1
Step 3
Demo On CodePen

Step 1:

If you don't already have a website, simply create an HTML file.

<!-- index.html -->

<!DOCTYPE html>
  <head>
    <title>Dark Mode Feature</title>
    <meta charset="UTF-8">
    <meta http-equiv="Content-type" content="text/html; charset=UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
  </head>

  <body>
    ...
  <body>
</html>
Enter fullscreen mode Exit fullscreen mode

Once you have that lets implement the HTML and CSS

Step 2:

In the basic HTML form lets now input everything we will need. Start by connecting your JS and CSS file. add

<!-- index.html -->

<!DOCTYPE html>
  <head>
    <title>Dark Mode Feature</title>
    <meta charset="UTF-8">
    <meta http-equiv="Content-type" content="text/html; charset=UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <!-- ADD CSS FILE -->
    <link rel="stylesheet" href="main.css">

    <!-- ADD JS FILE -->
    <script src="main.js"></script>
  </head>

  <body>
    ...
  <body>
</html>
Enter fullscreen mode Exit fullscreen mode

Now we need to create those two files. Feel free to change the name of your css and

In the CSS file we'll add these lines of code.

/* main.css */
body {
  background-color: white;
  color: black;
}

.dark-mode {
  background-color: black;
  color: white;
}
Enter fullscreen mode Exit fullscreen mode

Within the body we have specified that we want our default background to be white with black text. Then in the dark-mode class we've specified that we want want to change the background to black with white text.

Now we need to create the main.js file, the brain of our dark mode feature.

//main.js

function darkmode() {
  const wasDarkmode = localStorage.getItem('darkmode') === 'true';
  localStorage.setItem('darkmode', !wasDarkmode);
  const element = document.body;
  element.classList.toggle('dark-mode', !wasDarkmode);
}

function onload() {
  document.body.classList.toggle('dark-mode', localStorage.getItem('darkmode') === 'true');
}
Enter fullscreen mode Exit fullscreen mode

Once you've successfully created both the main.css and main.js files there's one last thing.

Step 3:

Though you may think you're done, you aren't. Ask yourself this very question. What if my website has multiple pages? how will each page stay in dark mode without returning to the default white background? The answer is far simpler than you think. In the initial body tag on each page add:

onload="onload()"
Enter fullscreen mode Exit fullscreen mode

That's it. Hope this was helpful! Thanks for reading!

Demo On CodePen

https://codepen.io/mattmarquise/details/MWbrNWe

Oldest comments (29)

Collapse
 
mattmarquise profile image
Matthew Marquise

Feel free to ask me any questions about this if you're having trouble.

Collapse
 
__manucodes profile image
manu

Instead of onload="onload()", I would prefer this, since you would only need to add one line to your page (<script src='script.js'></script>):

window.onload = function() {onload()}
Enter fullscreen mode Exit fullscreen mode

But otherwise, this is great!

Collapse
 
mattmarquise profile image
Matthew Marquise

Definitely works too! Thanks for the tip!

Collapse
 
anicode profile image
Abhis

welcome , my pleasure!

Collapse
 
0xwdg profile image
Wesley de Groot • Edited

You should use event listeners if you want to be on the safe side window.onload can be overwritten and eventlistener adds an listener to the page and will not be overwritten

Collapse
 
mattmarquise profile image
Matthew Marquise

Good point. However for this demo I wanted to keep it simple. For those who are into JS and have more than one function set for onload, they should understand how it works. But eventlistener is a great alternative.

Collapse
 
garybyrne profile image
Gary Byrne

Hey Matthew,

Yeah I agree with you. The dark/light mode toggle is a really popular feature and can really enhance a website.

Just from an accessibility point of view, If I was to have a toggle on my website I would first let it default to my OS dark/light mode.Then as that changes on the site you could consider then to use local storage.

We have a media query in CSS called prefers-color-scheme which we can access in JS with window.matchMedia.

web.dev/prefers-color-scheme :
This blog is really worth a read. It even talks about only loading CSS we need and not loading non critical CSS. You can also see the power of custom properties.

Collapse
 
mattmarquise profile image
Matthew Marquise

I will definitely read it because the preferred color scheme is a great feature to implement as well! Thanks Gary!

Collapse
 
icanswiftabit profile image
Błażej Wdowikowski • Edited

👋 Interesting approach but why not leave theme detection to browser?

:root {
    color-scheme: light dark;
    --special-text-color: #000
}

@media (prefers-color-scheme: dark) {
    :root {
        --special-text-color: #FFF;
    }
}

body, html {
    height: 100%;
    color-scheme: light dark;
}
Enter fullscreen mode Exit fullscreen mode
Collapse
 
mattmarquise profile image
Matthew Marquise

This is also a great way to do it!

Collapse
 
jonosellier profile image
jonosellier

Why not both?

@media (prefers-color-scheme: dark) {
    html.system {
        /* dark mode vars */
    }
}
html.dark {
    /* dark mode vars */
}
Enter fullscreen mode Exit fullscreen mode

And do the same check in the post but for a string via a switch. This also opens up the ability for different themes (maybe a dark mode that's actually light enough to blend in with the browser UI in dark mode, an amoled dark mode, a solarized mode, a few color-blind modes)

Collapse
 
garvitmotwani profile image
Garvit Motwani

Valuable information 👍🏻👍🏻

Collapse
 
krishan111 profile image
Krishan111

Thanks it really helped🙌

Collapse
 
ra1nbow1 profile image
Matvey Romanov

What`s wrong with prefers-color-scheme: dark?

Collapse
 
mattmarquise profile image
Matthew Marquise

Nothing wrong with that. using preferred color scheme is great, but also great to have a toggle.

Collapse
 
ug02fast profile image
Arthur Zhuk

Is there something wrong with just using the DarkReader extension?

Collapse
 
mattmarquise profile image
Matthew Marquise

Nothing wrong with that. And never said there was. This is just one way to achieve dark mode.

Collapse
 
ug02fast profile image
Arthur Zhuk

I just wonder why people are wasting time coding in dark themes when modern browsers have extensions to do that.

Thread Thread
 
mattmarquise profile image
Matthew Marquise

You have a good point

Thread Thread
 
ug02fast profile image
Arthur Zhuk

Actually mobile web pages still need it.

Collapse
 
harshsinha17 profile image
Harsh Sinha

Nice use of dark mode,
I've made a dark mode site please check it out here
d8wbyo.mimo.run/index.html
You have to click on clock's time display area to switch between modes :)

Collapse
 
mattmarquise profile image
Matthew Marquise

Love it!

Collapse
 
harshsinha17 profile image
Harsh Sinha

Thanks :-)

Collapse
 
dbarwikowski profile image
Daniel Barwikowski

I'm surprised that there is no "Dark Mode with service worker" yet

Collapse
 
Sloan, the sloth mascot
Comment deleted
Collapse
 
mattmarquise profile image
Matthew Marquise

Not sure what browser your in. All edges work for me.

Collapse
 
qz11 profile image
Yevazn

Great post!

I'm from HelloGitHub, a nonprofit organization in China. I am reaching out to you to ask if it's OK for us to translate your posts, "Implement Dark Mode On Your Website.", into Chinese and publish it on our WeChat official account. You own the copyright of course.

How does that sound to you?

Collapse
 
mattmarquise profile image
Matthew Marquise

As long as my Dev.to profile is linked and I'm credited that would be fine.

Collapse
 
yesminee profile image
yesminee

Thank you for this idea, but i have no clue why dark mode does not work in my web platform. (I am using admin LTE template) tho there is no error in my browser's console.