How awesome would it be to give your users the freedom to customize their interface to as per their preference? While many users prefer a light interface (light background with dark text), some users choose a dark interface (dark background with light text). Darker interfaces are perceived as cool and trendy while some also believe it reduces strain on the eyes especially for developers who spend a lot of time in front of the screen. I believe that providing an option to your users is a tremendous win in terms of accessibility and user experience. There are a couple of ways with which one can accomplish this. In this article, we will discuss on how to toggle between dark/light web design modes and implement this in Drupal 8 or Drupal 9.

Implementing the dark/light toggle


We will be focusing on two methods to implement this -
1.    Using only CSS.
2.    Implementing the CSS & JS toggle switch

Using only CSS

To achieve Dark mode on any website with only CSS, one must keep in mind some of the system requirements. One such important requirement is the system-wide dark mode. If a user prefers to use dark mode on his PC, then the user is served with a website which shows a dark-colored background with light text on it. The prefers-color-scheme (media query) is used to identify if the user has requested the system to use a light or dark color theme.

Implementation:

1.    Declare the CSS variables.
2.    Use the variables wherever it is necessary.

The result:
See the Pen Prefers-color-scheme (Auto dark/light mode) by Varun Rao (@varoonrao) on CodePen.

Note: To emulate the result on some unsupported devices, just enter DevTool by pressing F12. Next, press CTRL+SHIFT+P, then search for prefers-color-scheme: dark and press enter.  

Implementing the CSS and JS toggle switch

If we are going with this approach, then we don’t need to bother about the system requirements. Just write couple of lines of CSS and JS and you should be ready. Once we have initialized the variables, we can reference these variables in our stylesheets. This will be the HTML structure to toggle between dark and light mode.

HTML Structure


And some lines of CSS should result in this switch.

The switch

The final part is to add a bit of JavaScript to tie it all together.
●    Store the user preference for future visits
●    Check for saved user preference, if any, on load of the website

That's it! Check out the full demo below.

See the Pen DARK/LIGHT with js toggle switch by Varun Rao (@varoonrao) on CodePen.

Or click here to view the demo.

Implementing the Dark / Light Toggle in Drupal 8 (or Drupal 9)

To start with creating a custom Drupal 8 theme, please refer the awesome article here. Let us now start creating a theme to show how to use dark theme/ light theme in Drupal 8 or Drupal 9.
 
The file structure will look like this: 

Implementing the dark/light toggle

 

Now, update the header section inside the page.html.twig with the following code.


<header aria-label="Site header" id="header" role="banner">
    <div class="container">
      <div class="header">
        {{ page.branding }}
        {{ page.navigation }}
        <div class="switch-wrapper">
          <label class="switch" for="checkbox">
            <input type="checkbox" id="checkbox"/>
            <div class="slider round"></div>
          </label>
        </div>
      </div>
    </div>
  </header>

The rest of the HTML structure will be dependent on your design or requirements.
Once you are done with the HTML structure, it is time to make them look nice by styling the elements in CSS.
First, you have to create all the default variables which will be responsible for the colors on Light/ Dark mode.


style.css

:root {
  --color-background: #f0f0f0;
  --color-header: rgb(14, 33, 141);
  --color-header-text: #aecafa;
  --color-text: #2c0000;
  --color-card-bg: #fff;
  --color-link: rgb(255, 0, 0);
}
/* Variable decleration for dark mode */
[data-theme="dark"] {
  --color-background: #1a1a1a;
  --color-header: #aecafa;
  --color-header-text: 0e218d;
  --color-text: #d3d3d3;
  --color-card-bg: #435561;
  --color-link: #24ce24;
}

Now that you are done defining the variables, it is time to add style to the Header section to get the required result.


style.css
.header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px;
  border-bottom-right-radius: 10px;
  border-bottom-left-radius: 10px;
  background-color: var(--color-header);
}

.header a {
  color: var(--color-header-text);
  text-decoration: none;
  font-weight: bold;
}

.region-navigation {
  display: flex;
  justify-content: center;
}

ul.menu {
  display: flex;
  justify-content: center;
}

ul.menu li {
  margin-right: 30px;
}

.switch-wrapper {
  display: flex;
  align-items: center;
}

.switch {
  display: inline-block;
  height: 34px;
  position: relative;
  width: 60px;
}

.switch input {
  display: none;
}

.slider {
  background-color: white;
  bottom: 0;
  cursor: pointer;
  left: 0;
  position: absolute;
  right: 0;
  top: 0;
  transition: 0.4s;
}

.slider:before {
  background-color: rgb(255, 196, 0);
  bottom: 4px;
  content: url("../assets/sunny-day.svg");
  height: 26px;
  left: 4px;
  position: absolute;
  transition: 0.4s;
  width: 26px;
}

input:checked + .slider {
  background-color: rgb(36, 36, 36);
}

input:checked + .slider:before {
  transform: translateX(26px);
  content: url("../assets/night.svg");
  background-color: rgb(59, 116, 223);
}

.slider.round {
  border-radius: 34px;
}

.slider.round:before {
  border-radius: 50%;
}

Please note that the styling may vary according to your requirements. After all the styling, it is now time to write some functionality in Jquery code. The Jquery code will look something like this (script.js in our case)


script.js

(($, Drupal) => {
  Drupal.behaviors.mainMenu = {
    attach(context) {
      const toggleSwitch = document.querySelector(
        '.switch input[type="checkbox"]'
      );
      const currentTheme = localStorage.getItem("theme");

      if (currentTheme) {
        document.documentElement.setAttribute("data-theme", currentTheme);

        if (currentTheme === "dark") {
          toggleSwitch.checked = true;
        }
      }

      function switchTheme(e) {
        if (e.target.checked) {
          document.documentElement.setAttribute("data-theme", "dark");
          localStorage.setItem("theme", "dark");
        } else {
          document.documentElement.setAttribute("data-theme", "light");
          localStorage.setItem("theme", "light");
        }
      }

      toggleSwitch.addEventListener("change", switchTheme, false);
    },
  };
})(jQuery, Drupal);

And don’t forget to include your JS and CSS files inside your theme_name.libraries.yml file.


global-styling:
  version: 1.x
  css:
    theme:
      css/style.css: {}
  js:
    js/script.js: {}
  dependencies:
    - core/jquery
- core/drupal

Now clear the site cache to see the result. Your end result should look like this :

Result

 

toggle between Dark and Light Mode in Drupal 8

 

Contact us

LET'S DISCUSS YOUR IDEAS. 
WE'D LOVE TO HEAR FROM YOU.

CONTACT US