Feeds

Author

Upgrade Your Drupal Skills

We trained 1,000+ Drupal Developers over the last decade.

See Advanced Courses NAH, I know Enough
Sep 15 2020
Sep 15

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:

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                                               HTML Structure


And some lines of CSS should result in this switch.

The switchThe 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.

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.

page.html.twig

  <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 :

Resulttoggle between Dark and Light Mode in Drupal 8

About Drupal Sun

Drupal Sun is an Evolving Web project. It allows you to:

  • Do full-text search on all the articles in Drupal Planet (thanks to Apache Solr)
  • Facet based on tags, author, or feed
  • Flip through articles quickly (with j/k or arrow keys) to find what you're interested in
  • View the entire article text inline, or in the context of the site where it was created

See the blog post at Evolving Web

Evolving Web