DEV Community

Cover image for How to Switch Your Website to Dark Mode Using CSS and JavaScript
Mohammad Sarabi
Mohammad Sarabi

Posted on

How to Switch Your Website to Dark Mode Using CSS and JavaScript

Introduction

Dark mode is a display setting that uses a dark background with light text and elements. It has gained popularity because it looks good and offers several practical benefits.

The benefits of dark mode include:

  1. Reduced Eye Strain: Dark mode can be easier on the eyes, especially in low-light environments, as it reduces the amount of bright light emitted from screens.
  2. Improved Battery Life on OLED Screens: On OLED (Organic Light Emitting Diode) screens, dark mode can save battery life because black pixels are essentially turned off, consuming less power compared to displaying bright colors.

In this tutorial, we will cover how to switch your website to dark mode using CSS and JavaScript. We will start with a simple light-themed web page template and transform it into a website with a toggleable light/dark mode, allowing users to switch between light and dark themes smoothly.

Setting Up the Project

Let's start with a simple light-themed web page template. Then, we'll transform it into a website with a toggleable light/dark mode, allowing users to switch between light and dark themes.

Implementing Dark Mode Styles

Choosing the Colors

The first step is to list all the colors we are using and choose a dark-theme version for each one. In the table below, I have listed all the colors on the page and their corresponding dark versions.

Name Light version Dark version
body-bg #f4f4f4 #121212
primary-text #333333 #e0e0e0
header-footer-bg #333333 #181818
header-footer-text #ffffff #ffffff
section-bg #ffffff #1f1f1f
secondary-text #006baf #1e90ff
shadow rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.2)

Custom Variables

We then use CSS variables to create a dark and light class on body with those variables.

body.dark {
    --body-bg: #121212;
    --primary-text: #e0e0e0;
    --header-footer-bg: #1f1f1f;
    --header-footer-text: #ffffff;
    --section-bg: #1f1f1f;
    --secondary-text: #1e90ff;
    --shadow: rgba(0, 0, 0, 0.2);
}

body.light {
    --body-bg: #f4f4f4;
    --primary-text: #333333;
    --header-footer-bg: #333333;
    --header-footer-text: #ffffff;
    --section-bg: #ffffff;
    --secondary-text: #006baf;
    --shadow: rgba(0, 0, 0, 0.1);
}
Enter fullscreen mode Exit fullscreen mode

You can read about CSS variables in Using CSS custom properties. Essentially, they are entities defined using two dashes (--) that store values for reuse in a document. CSS variables make maintenance easier by allowing changes to update automatically.

Dynamic Element Colors

We use the var() CSS function to insert the values of the CSS variables. This way, we can dynamically change the color and update one variable to reflect changes across the entire document, instead of changing each one manually.

Here is an example of the nav element and its children:

body {
  background-color: var(--body-bg);
  color: var(--primary-text);
}

header, footer {
  background-color: var(--header-footer-bg);
  color: var(--header-footer-text);
}

article {
  background-color: var(--section-bg);
  box-shadow: 0 4px 8px var(--shadow);
}

a {
  color: var(--secondary-text);
}
Enter fullscreen mode Exit fullscreen mode

Toggle Light/Dark Mode with JavaScript

Now we can change the class of the body to dark or light to switch the theme. First, add a button to the header and set the changeTheme() function for its click event:

<button onclick="changeTheme()" class="theme-toggle">
    <svg> <!-- icon --> </svg>
</button>
Enter fullscreen mode Exit fullscreen mode

Define the changeTheme() function that toggles the class of the body:

function changeTheme() {
    if (document.body.classList.contains('light')) {
        document.body.classList.remove('light');
        document.body.classList.add('dark');
    } else {
        document.body.classList.remove('dark');
        document.body.classList.add('light');
    }
}
Enter fullscreen mode Exit fullscreen mode

And now users can change the theme of the website by clicking on the button.

You can see the code of the tutorial in the CodePen below

Next Steps

Additionally, you could store the user's theme preference in local storage. Updating the changeTheme() function to save the selected theme and check for it when the page loads will ensure the user's choice is remembered and applied automatically on their next visit.

function changeTheme() {
    if (document.body.classList.contains('light')) {
        document.body.classList.remove('light');
        document.body.classList.add('dark');
    } else {
        document.body.classList.remove('dark');
        document.body.classList.add('light');
    }

    // Save the current theme in localStorage
    const theme = document.body.classList.contains('dark') ? 'dark' : 'light';
    localStorage.setItem('theme', theme);
}

document.addEventListener('DOMContentLoaded', function () {
    // Get the saved theme from localStorage when the page loads
    const savedTheme = localStorage.getItem('theme') || 'light';
    document.body.classList.add(savedTheme);
});
Enter fullscreen mode Exit fullscreen mode

Adding the color-scheme: dark; property when in the dark theme can also ensure that some elements, which are otherwise hard to style, will have their styles changed by the browser.

body.dark {
  color-scheme: dark;
}
Enter fullscreen mode Exit fullscreen mode

Conclusion

In conclusion, adding dark mode to your website can improve user experience by reducing eye strain and extending battery life on OLED screens. By following this guide, you can easily set up a light/dark mode toggle using CSS and JavaScript. Customize the dark mode to fit your design.

Share your implementations or ask questions in the comments below.

Top comments (4)

Collapse
 
mardeg profile image
Mardeg

An additional step I took on this page is to use @media (prefers-color-scheme: dark) for people who already have their browser/system on a dark theme, and then provide the choice to go light, and vice versa outside the media query.

I also decided to use the CSS :checked selector with a checkbox/label instead of using javascript, although that means no preference is stored (unless you count Firefox's form caching behaviour).

Collapse
 
msarabi profile image
Mohammad Sarabi

And in case you want to use JavaScript for that as well you can check for window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches instead of defaulting to light mode.

Collapse
 
annavi11arrea1 profile image
Anna Villarreal

Yes this is so simple and exactly what I needed to read. Thank you for posting this! You have laid it out in a super understandable manner.

Collapse
 
msarabi profile image
Mohammad Sarabi

Thank you! I'm glad you found it helpful.