Parashar developer


Dark Mode

It's not surprising that dark mode is the new fad in the town after Apple introduced the dark mode in MacOS. I decided to add a toggle button to switch to the dark theme on my blog.

May 29, 2020  ×  2 mins read

Let’s establish a few ground rules of engagement:

  1. The default theme of the blog must always be the light theme. For example, if the user’s device does not define the prefers-color-scheme CSS rule then we apply the default theme.
  2. We must respect the mode the user’s device is currently switched to and override the blog’s theme to match that mode. For example, if the user’s device is using the dark mode, then we apply the .dark theme to the blog and vice versa.
  3. We must always provide the user with an option to toggle between the light and the dark theme for the blog.
  4. If the user’s device is running on dark mode and the user decides to switch to the light theme, then all subsequent pages should use the light theme, and vice versa.
  5. The behavior defined in #4 should reset when the tab or the browser window is closed.

Step 1

Define the light and dark theme for your site in CSS. Apply the .light class by default to the body of the document.

.light {
  --level-0: #fff;  --text-0: #000;
  --level-1: #eee;  --text-1: #333;
  --level-2: #ddd;  --text-2: #666;
.dark {
  --level-0: #111;  --text-0: #fff;
  --level-1: #222;  --text-1: #ccc;
  --level-2: #333;  --text-2: #999;

Step 2

Its now time to add a toggle button that will toggle the theme each time it is clicked.

<a role="button" 
   title="Toggle between Dark and Light theme">Light/Dark</a>

Step 3

We use sessionStorage instead of localStorage so that saved theme gets wiped out after the tab or window is closed. This covers the requirement #5.

  const btn = document.querySelector(".btn-toggle");
  const prefersDarkScheme = window.matchMedia("(prefers-color-scheme: dark)");

  if(sessionStorage.getItem("theme") != null){
    document.body.className = sessionStorage.getItem("theme");
  else if(prefersDarkScheme.matches){
  btn.addEventListener("click", function(e){
    return false;

Did you enjoy reading this artice? I'd love to hear your thoughts. Feel free to send me a tweet or open an issue on Github to add your comments.

What's new in Python 3.9

Look Ma! No Media Queries


Back to Top