This site uses third-party cookies, learn more or accept
dark light

Dark/Light mode - HTML and CSS, JavaScript if you'd like

Written by Max Pelic on

In this tutorial, I'll show you a few different methods of enabling a light/dark mode toggle switch, and the pros and cons to each. The examples will include support for the new prefers-color-scheme media query.

Here's an example of what a pure CSS dark mode toggle switch will end up looking like: Pure CSS dark/light toggle

So, let's dive right in:

Method 1: Pure CSS mode toggle button

The first method I'll cover is making a pure CSS toggle button. This is just a basic example, make sure you customize this to fit the style of your site.

We'll start by creating a basic HTML page. We'll include a checkbox and label that we'll end up turning into the toggle button, and a <main> section to hold all of the page's content.

1<!doctype html>

2<html>
3<head>
4 <title>Darkmode Example</title>
5 <!-- css will go here -->
6</head>
7<body>
8 <input type="checkbox" name="toggleMode" id="toggleMode"><label for="toggleMode"></label>
9 <main>
10 <!-- put your main content here -->
11 </main>
12</body>
13</html>

Next, let's start adding some CSS. Personally, I prefer to use CSS Variables do we don't have to update every element with two styling rules.

In this example, we'll have two variables: --background for the background of the page, and --color for the color of the content. These variables will be declared for the <main> element so we can change them based on the checkbox's state.

1main{

2 --color:black;
3 --background:white;
4}

The next step is to change these variables when the checkbox is checked. Will do this by using the Genral Sibling Combiner (~) and the :checked selector.

1#toggleMode:checked ~ main{

2 --color:white;
3 --background:black;
4}

We now have a basic toggle switch created. Let's update the label based on the current mode, do people know what will happen when they click on it. We can also hide the checkbox since clicking on the label will toggle it. We'll use the :before pseudo-element to update the label's text.

1#toggleMode{

2 display:none;
3}
4#toggleMode + label:before{
5 content:'enable dark mode';
6}
7#toggleMode:ckecked + label:before{
8 content:'enable light mode';
9}

Here's all the CSS we have so far:

1main{

2 --color:black;
3 --background:white;
4}
5#toggleMode:checked ~ main{
6 --color:white;
7 --bakcground:black;
8}
9#toggleMode{
10 display:none;
11}
12#toggleMode + label:before{
13 content:'enable dark mode';
14}
15#toggleMode:ckecked + label:before{
16 content:'enable light mode';
17}

So far, we've created a basic functioning mode toggle switch. In the next part, let's explore adding support for the prefers-color-scheme media query.

Adding support for prefers-color-scheme

If you haven't heard about it yet, the prefers-color-scheme media query lets you check what color scheme is selected on an OS level - here's more information on that.

To implement prefers-color-scheme, we'll basically make a media query with the opposite CSS as we had before.

Let's start by creating a media query for prefers-color-scheme:

1@media (prefers-color-scheme:dark){

2 /** default to dark mode here **/
3}

Next, we'll add CSS that works the opposite way as the previous code - default to dark mode and let users toggle to light mode.

The code below should be placed inside the previous media query.

1/** default to dark mode **/

2main{
3 --color:white;
4 --background:black;
5}
6#toggleMode:checked ~ main{
7 --color:black;
8 --background:white;
9}

We'll also need to update the label to reflect the default dark mode (again, this should be placed inside the media query):

1#toggleMode + label:before{

2 content:'enable light mode';
3}
4#toggleMode:ckecked + label:before{
5 content:'enable dark mode';
6}

There you go - the mode will automatically default to dark mode when prefers-color-scheme is set to dark.

Lastly, let's explore another method of using JavaScript to create a dark mode.

JavaScript dark mode

In this method, we'll use JavaScript to change the mode of the page. The advantage of using JavaScript is the ability to save the user's preference, and next time they load the page you can load it with their preference still selected.

In this example, we'll use a button to update the color mode.

1<!doctype html>

2<html>
3<head>
4 <title>JavaScript dark mode</title>
5 <!-- css will go here -->
6</head>
7<body>
8 <button id="toggleMode">toggle dark mode</button>
9 <script>
10 //javascript goes here
11 </script>
12 <!-- main content goes here -->
13</body>
14</html>

In this example, we'll be adding the dark mode via a class we add to the <html> element. Then we can create a separate CSS selector for dark mode by using .dark. I won't include the dark mode CSS here because it should be pretty easy to figure out.

Here's how we'll update the class using javascript:

1//default to light mode

2
var mode = 'light';
3if (localStorage.getItem("mode")){
4 //check if there's a saved state already
5
mode = localStorage.getItem("mode");
6} else if (window.matchMedia('(preferes-color-scheme:dark)')){
7 //check if dark mode is preferred
8
mode = "dark";
9}
10//update the class based on the mode
11
document.documentElement.className = mode;
12
13//when the button is clicked, toggle the mode and save the change in local storage
14
document.getElementById('toggleMode').onclick = function(){
15 mode = (mode === 'dark') ? 'light' : 'dark';
16 document.documentElement.className = mode;
17 localStorage.setItem("mode", mode);
18}

That's the basics of implementing a dark mode. Try it out and see what you think, you can email any questions or thoughts to max@maxpelic.com.

Share this article:

Previous Article: Check the OS color scheme: prefers-color-scheme in CSS

Next Article: Password Generator