In this tutorial, you will learn how to implement dark and light mode toggle feature to a website using CSS, and JavaScript.
What is the way to build dark and light mode functionality?
It is up to you how you can build it. Here I will show you one of the best ways to do that which is – Using CSS custom properties.
First, we define the colors for the light mode to the CSS custom properties. Like the following –
:root {
--color:#222222;
--bg-color:#f7f7f7;
--main-bg-color:white;
}
After that, we have to define colors for the dark mode in the same custom properties, but this time the selector will be the same but with the [dark-theme]
attribute.
:root[dark-theme] {
--color:#cccccc;
--bg-color:#1a1a1a;
--main-bg-color:#111111;
}
So the colors have been defined, now if you set the dark-theme attribute on the root element (<html>
), the :root[dark-theme]
color will be applied to the entire website.

You can dynamically set this dark-theme
attribute to the root element by using following JavaScript code –
document.documentElement.setAttribute('dark-theme',true);
Example of dark and light mode

<!DOCTYPE html>
<html lang="en">
<head>
<title>Dark and Light Mode Example</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Open+Sans:wght@700&display=swap" rel="stylesheet">
<style>
*,
*::before,
*::after {
box-sizing: border-box;
line-height: 1.5em;
}
:root {
--color: #222222;
--bg-color: #f7f7f7;
--main-bg-color: white;
}
:root[dark-theme] {
--color: #cccccc;
--bg-color: #1a1a1a;
--main-bg-color: #111111;
}
html {
font-size: 16px;
-webkit-text-size-adjust: 100%;
}
body {
margin: 0;
padding: 20px;
overflow-wrap: break-word;
font-family: "Open Sans", sans-serif;
color: var(--color);
background-color: var(--bg-color);
-moz-osx-font-smoothing: grayscale;
-webkit-font-smoothing: antialiased;
}
main {
max-width: 900px;
margin: 0 auto;
background-color: var(--main-bg-color);
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1),
0 4px 6px -4px rgba(0, 0, 0, 0.1);
padding: 30px;
border-radius: 3px;
}
h1 {
text-align: center;
font-size: 2rem;
}
.change-theme-btn {
text-align: center;
}
.change-theme-btn button {
all: unset;
font-size: 5rem;
cursor: pointer;
border: 1px solid;
padding: 10px;
border-radius: 50%;
overflow: hidden;
}
.change-theme-btn button.light .sun {
visibility: hidden;
}
.change-theme-btn button.dark .moon {
visibility: hidden;
}
.change-theme-btn button.dark .sun {
visibility: visible !important;
}
</style>
</head>
<body>
<main class="container">
<h1>Dark and Light Mode</h1>
<div class="change-theme-btn">
<button id="themeChanger" class="light"><svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="svg-icon"><path class="moon" d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/><g class="sun"><circle cx="12" cy="12" r="5"></circle><line x1="12" y1="1" x2="12" y2="3"></line><line x1="12" y1="21" x2="12" y2="23"></line><line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line><line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line><line x1="1" y1="12" x2="3" y2="12"></line><line x1="21" y1="12" x2="23" y2="12"></line><line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line><line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line></g></svg></button>
</div>
</main>
<script>
const themeChanger = document.getElementById('themeChanger');
themeChanger.onclick = function(){
themeChanger.classList.toggle("dark");
document.documentElement.toggleAttribute('dark-theme');
if(themeChanger.classList.contains('dark')){
localStorage.setItem('theme','dark');
return;
}
localStorage.setItem('theme','light')
}
window.onload = function(){
const theme = localStorage.getItem('theme');
if(theme && theme === 'dark'){
themeChanger.classList.add('dark');
document.documentElement.setAttribute('dark-theme',true);
}
}
</script>
</body>
</html>