How To Add Dark Mode To Your Website or App Using Alternate Style Sheets

dark mode pwa css alernate style sheets dynamic theme switch tutorial

Coding Book Deals

Get all of my books for $1/month on Patreon or get my coding book bundle!

Adding Dark Mode To Your Site

Dark Mode has been implemented by many popular sites and apps such as Twitter, Instagram, WhatsApp and YouTube. But how to add it on your own site?

I've always been fascinated by dynamic site color theme switchers. They offer improved user experience by allowing you to choose a color theme you feel at home with!

For example, here is Twitter's color options found under Display Settings.

Twitter's theme switcher

Let's create something similar. Perhaps it won't be as fancy as Twitter's theme changer but we'll cover technical aspects using alternate style sheets and JavaScript to switch on a CSS set containing theme definition.

First... let's take a look at what we are trying to create here.

Below is a working example that will switch theme of this site.

Dark
Super
Dark
Light
Blue
Green
CLICK on buttons to instantly switch CSS theme of this entire site. In the remainder of this tutorial I'll show you how to add Dark Mode functionality to your own site!

If you can grasp alternate stylesheets in this Dark Mode tutorial you can replicate it on your custom website, in Wordpress (or similar site-building tool.)

You may have heard CSS can be inline, internal and external. This determines how CSS is included in your document. But to understand alternate style sheets we first need to take a look at...

The 3 Types Of Cascading Style Sheets

But there are 3 other different ways of thinking about Cascading Style Sheets. They are persistent, preferred and alternate.

  • Persistent is the CSS style that is always enabled and combined together with active style sheet. In order to specify persistent style sheet add rel = "stylesheet" attribute to your link tag and skip title attribute.

    This is just your regular way of specifying a style sheet.

<!-- Persistent Style Sheet -->
<link src = "style.css" rel = "stylesheet" />
  • Preferred stylesheet is your default style enabled when the page has finished loading. To create it add title attribute to your CSS link tag.
<!-- Preferred Style Sheet (just add a title) -->
<link src = "dark.css"
      rel = "stylesheet"
    title = "dark" />
  • Alternate can be swapped in real time to change theme without reloading the page.
<!-- Dark Mode Alternate Style Sheet -->
<link src = "dark.css"
    title = "dark" />
      rel = "alternate stylesheet" />
<!-- Light Mode Alternate Style Sheet -->
<link src = "light.css"
    title = "light"
      rel = "alternate stylesheet" />

In order to create alternate sheet all you have to do is set rel attribute in your link tag to "alternate stylesheet". That's pretty much it.

This is just the first step. Now we need to write a script to switch style sheets.

Switching Between Style Sheets Dynamically

When I was doing my research I found a couple of older alternate style sheet JavaScript functions floating around the internet. But they were a bit outdated so I wrote my own.

The bottom line is you need to set property disabled to false on the alternate style sheet object that you want to enable.

<!-- Switch to a named alternate stylesheet -->
function setActiveStyleSheet(title) {
    let css = `link[rel="alternate stylesheet"]`;
    let stylesheets = document.querySelectorAll(css);
    stylesheets.forEach(sheet => sheet.disabled = true);
    let selector = `link[title="${title}"]`;
    let stylesheet = document.querySelector(selector);
    stylesheet.disabled = false;
}

To switch to a new stylesheet dynamically, first you have to disable all available alternate stylesheets. If you fail to do this you will find your alternate stylesheet not working (not switching.)

So as the first step in this function we disable all available alternate stylesheets. Once done, we enable the one specified in title argument.

<!-- Attach event to a button -->
    let DarkModeButton = document.getElementById("DarkModeButton");
    DarkModeButton.addEventListener("click",
        event => setActiveStyleSheet("darkmode"));

You can attach setActiveStyleSheet function as a callback for the "click" event on the button responsible for switching it on. Note the example above assumes we have a stylesheet with title = "darkmode".

Or you can simply use onclick attribute directly on the element:

<div id = "DarkModeButton"
onclick = "setActiveStyleSheet('darkmode')"></div>

That's all, as far as switching CSS stylesheets dynamically is concerned. But there is one more thing!

If the user leaves the site after having chosen an alternate theme, we need to make sure when the user comes back that we load the last chosen theme. This can be done using cookies, but in this tutorial I'll do it using HTML5 localStorage.

Memorizing Selected Theme

We can use localStorage to memorize previously selected theme. The code is straight-forward. Every time a theme is selected, we will store its title name in a localStorage item named "theme". Let's update the function we've already written in previous step:

<!-- Switch to a named alternate stylesheet -->
function setActiveStyleSheet(title) {
    let css = `link[rel="alternate stylesheet"]`;
    let stylesheets = document.querySelectorAll(css);
    stylesheets.forEach(sheet => sheet.disabled = true);
    let selector = `link[title="${title}"]`;
    let stylesheet = document.querySelector(selector);
    stylesheet.disabled = false;
    localStorage.setItem("theme", title);
}

Notice a new localStorage call was added. Now every time an alternate style sheet is switched on it will be stored under keyword "theme".

Now, if user leaves the site and re-enters it again (after closing browser tab) we need to restore default theme that was saved in localStorage.

To do this, let's read from local storage on DOMContentLoaded event (soon after DOM finished loading in its entirety) and use the value stored in theme item to select the stylesheet:

<!-- Switch to a named alternate stylesheet -->
window.addEventListener('DOMContentLoaded', (event) => {
    console.log('DOM fully loaded and parsed');
    let title = localStorage.getItem("theme");
    setActiveStylesheet(title);
})

That's it! Now you have a complete alternate CSS theme theme selector. The hard part is of course making a pretty CSS layout. But that can wait until another tutorial!

Thanks For Reading. Check Out My Coding Books!

My coding books are available in paperback, Kindle and PDF formats. Check out these links below to "look inside" and learn more!

Amazon (paperback, Kindle) and as instant download in PDF format.

js javascript and css visual dictionary pdf coding book download

Amazon (paperback, Kindle)

You can get it as an instant download in PDF format here.

js javascript and css visual dictionary pdf coding book download

Amazon (paperback, Kindle)

You can get it as an instant download in PDF format here.