Create a Dark/Light or Custom Color Theme using CSS and Javascript

Color Theme Switch: Set a light or dark or any other custom color theme for your website using CSS variables and Javascript

 Yogesh    04 Sep, 2020    44

It is more essential to have a multiple(/dark/light) color theme of your website/blog to attract more people. In today's web, most of the popular websites have multiple(dark/light) color themes available.

The color modes enhance the overall look and feel of the website from the UI perspective.

To create the color themes, we will use the CSS variables(for colors) and Javascript(to toggle and store the user preference).

In this tutorial, we will learn how to change the theme from light(default) to dark and other custom color themes.

To create the Color theme switcher, follow the simple steps:

First, we will create the CSS class that contains color variables for the default(light) theme then add that class to the body tag.

In this primary section, we will create a dynamic color variable in CSS: bg(for backgorund color), --bg-light(bg light variant), --clr-text(title, heading text colors), --clr-element(theme primary color)… 

In the CSS file we've added variables using the both methods, using class and using attribute. You can use any one of them according to your need.

CSS Class for Default(light) Theme

.light, body[color-theme="light"] {
  --bg: #f0f8ff;
  --bg-light: rgba(255, 255, 255, .8);
  --clr-text: #182227;
  --clr-text-light: #182227bb;
  --clr-element: #34506e;
  --clr-element-hover: #34506ebb;
  --clr-shadow: rgba(0, 0, 0, .15);
}

CSS Class for Dark Theme

.dark, body[color-theme="dark"] {
  --bg: #182227;
  --bg-light: rgba(255, 255, 255, .15);
  --clr-text: #FCE8Ec;
  --clr-text-light: #FCE8Ecbb;
  --clr-element: #FFABC2;
  --clr-element-hover: #FFABC2bb;
  --clr-shadow: rgba(0, 0, 0, .2);
}

CSS Class for Solarized Theme

.solarized, body[color-theme="solarized"] {
  --bg: #002b36;
  --bg-light: rgba(255, 255, 255, .15);
  --clr-text: #fdf6e3;
  --clr-text-light: #fdf6e3bb;
  --clr-element: #93a1a1;
  --clr-element-hover: #93a1a1bb;
  --clr-shadow: rgba(0, 0, 0, .2);
}

CSS Class for Blue Theme

.blue, body[color-theme="blue"] {
  --bg: #0b3393;
  --bg-light: #5f8eff73;
  --clr-text: #bed7ff;
  --clr-text-light: #bed7ffdd;
  --clr-element: #7ebcff;
  --clr-element-hover: #7ebcffbb;
  --clr-shadow: rgba(0, 0, 0, .15);
}

You can customize the colors according to your theme preference.

Also, we can set the global variables in :root pseudo selector for general use that can apply on any theme.

Global CSS Variables

:root {
  --pf: 'Source Sans Pro', sans-serif;
  --transition: all .5s;
}

Then apply the transition to all elements. Because of this transition, it will give user smooth effects while changing the themes.

Apply a transition(purpose: smooth switching) to all the elements

* {
  transition: var(--transition);
}

Then, apply these variables in our CSS:

CSS Stylesheet

body {
  background: var(--bg);
  font-family: var(--pf);
  transition: var(--transition);
  border-bottom: 10px solid var(--clr-element);
}
.title {
  font-family: var(--pf);
  color: var(--clr-text);
  font-weight: 800;
  font-size: 2.5rem;
  .
  .
}
.box {
  padding: 2rem;
  border: 2px solid var(--clr-element);
  border-radius: 5px;
  color: var(--clr-text);
  display: flex;
  align-items: center;
  justify-content: center;
}
.card {
  background: var(--bg-light);
  box-shadow: 0 2px 10px var(--clr-shadow);
  padding: 1rem;
  border-radius: 5px;
  transition: all .2s;
}
.
.
.
/* your css */
.

Next, we will create an HTML page structure.

HTML Structure

<body id="body" class="light"> // using class
.
.
/* your code
.
.
</body>
<body color-theme="dark"> // using attribute
.
.
</body>

[# see the demo for more color themes]

In the above markup, we will replace the body class to activate the current theme using Javascript.

The body tag contains only one theme class else color switch will not work using this method. If your body have other custom classes then you can use custom data attributes to select the theme. Like <body dd-theme="dark"> and change the attribute instead of class. We will add both the methods in this tutorial.

Next, we will add the Switch to toggle the Light and Dark theme using Javascript. Also, we will save the selected theme in the localStorage.

HTML Markup for Theme Switcher, or Theme Selector.

<div class="box">
  // Toggle switcher(dark/light)
  <span dd-toggle="theme" class="df">
    <div id="toggle_theme" class="dd-theme__switcher">
      <span class="dd-theme__switcher-btn">
        <svg xmlns="http://www.w3.org/2000/svg" class="dd-icon icon-tabler icon-tabler-sun" width="24" height="24"
          viewBox="0 0 24 24" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round">
          <path stroke="none" d="M0 0h24v24H0z" />
          <circle cx="12" cy="12" r="4" />
          <path d="M3 12h1M12 3v1M20 12h1M12 20v1M5.6 5.6l.7 .7M18.4 5.6l-.7 .7M17.7 17.7l.7 .7M6.3 17.7l-.7 .7" />
        </svg>
        <svg xmlns="http://www.w3.org/2000/svg" class="dd-icon icon-tabler icon-tabler-moon" width="24" height="24"
          viewBox="0 0 24 24" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round">
          <path stroke="none" d="M0 0h24v24H0z" />
          <path d="M16.2 4a9.03 9.03 0 1 0 3.9 12a6.5 6.5 0 1 1 -3.9 -12" />
        </svg>
      </span>
    </div>
    &nbsp;<label class="box-lbl" for="toggle_theme"><strong>Toggle Ligth/Dark Theme</strong></label>
  </span>&nbsp;| Or |&nbsp;
  // Other Available Themes
  <label dd-theme="solarized" class="theme--label">
    <span></span>Solarized color theme
  </label>&nbsp;
  <label dd-theme="pt" class="theme--label">
    <span></span>Pink-Teal color theme
  </label>&nbsp;
  <label dd-theme="blue" class="theme--label">
    <span></span>Blue color theme
  </label>&nbsp;
  <label dd-theme="yp" class="theme--label">
    <span></span>Yellow-Purple color theme
  </label>&nbsp;
</div>

CSS for Theme Switcher/Selector

.dd-icon {
  stroke: var(--clr-text);
}
.dd-theme__switcher {
  position: relative;
  overflow: hidden;
  display: inline-block;
  width: 25px;
  height: 25px;
  cursor: pointer;
}
.dd-theme__switcher .dd-theme__switcher-btn {
  position: absolute;
  display: flex;
  flex-direction: column;
  transition: var(--transition);
  top: 0;
}
body.light .dd-theme__switcher .dd-theme__switcher-btn {
  top: -24px;
}
.theme--label {
  display: flex;
  align-items: center;
  border: 2px solid var(--clr-element);
  padding: 5px 10px;
  border-radius: 4px;
  margin: 0 10px;
  cursor: pointer;
}
.theme--label span {
  position: relative;
  display: inline-block;
  width: 25px;
  height: 25px;
  border-radius: 25px;
  margin-right: 10px;
}
.theme--label[dd-theme="solarized"] span {
  background: #002b36;
}
.theme--label[dd-theme="pt"] span {
  background: #5cbdb9;
}
.theme--label[dd-theme="blue"] span {
  background: #7ebcff;
}
.theme--label[dd-theme="yp"] span {
  background: #7d3cff;
}
.theme--label[dd-theme].active {
  color: var(--bg);
  background: var(--clr-element);
}
.theme--label[dd-theme].active span { background: var(--bg); }

Next, we will add the javascript to change the themes and store the selected theme in localStorage.

In javascript, we will do the following tasks to activate & store the selected theme.

  • Check if localStorage has already saved your preference(theme) and if yes then assign it to the body class.
  • Add event listeners to deactivate the previous theme and activate the current theme.
  • And save our theme in localStorage for the future.

Javascript to toggle between light and dark theme & localStorage

// Set the theme from localStorage(if exist) || or set default light
let theme = window.localStorage.getItem('theme') || 'light';
// Activate the current theme (using class)
body.classList = theme;
// Available Themes
let available_themes = document.querySelectorAll('[dd-theme]');

/** Light / Dark theme Toggle */
// Toggle Dark / Light theme
let _toggler = document.querySelector('[dd-toggle]');
_toggler.addEventListener('click', toggleTheme);
// Function: toggle theme(light & dark)
function toggleTheme() {
 // Toggle light / dark theme
 ( theme == 'light' ? theme = 'dark' : theme = 'light');
 // Apply class to body
 body.classList = theme;
 // Store theme var to localStorage
 window.localStorage.setItem('theme', theme );
}

If your web project contains more then 2 themes then you can activate/deactivate the theme using the below code.

Javascript to activate/deactivate from multiple themes & localStorage

/** Switch Theme **/
// Set the theme from localStorage(if exist) || or set default light
let theme = window.localStorage.getItem('theme') || 'light';
// Activate the current theme
body.classList = theme;

// Available Themes
let available_themes = document.querySelectorAll('[dd-theme]');
available_themes.forEach(e => {
 ( window.localStorage.getItem('theme') == e.getAttribute('dd-theme') ? e.classList.add('active') : null );
 e.addEventListener('click', switchTheme);
});
function switchTheme() {
 available_themes.forEach(e => {
   e.classList = 'theme--label';
 });
 let theme = this.getAttribute('dd-theme');
 this.classList.add('active');
 body.classList = theme;
 window.localStorage.setItem('theme', theme);
}

If you want to use an attribute to switch the theme instead of body class then replace the below line

body.classList = theme;

with

body.setAttribut('color-theme', theme);

in the above Javascript code.

Reference website with multi-color theme: Alligator.io

I also recommend these color palette generators: Coolors, Muzli Colors, and Color Space to generate the color codes for your themes. 

I really hope that you guys find this article useful. Share your thoughts/suggestions. 

Thanks!