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.
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.
And some lines of CSS should result in this 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:
Now, update the header section inside the page.html.twig with the following code.
page.html.twig
{{ page.branding }}
{{ page.navigation }}
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 :