Weekly Webtips
Published in

Weekly Webtips

How to Implement dark/light mode in CSS.

Image by Juan Cruz Martinez

If you have ever written CSS for a large web app then you know how hard it is to manage CSS. Add that to the increasing need to support dark and light modes in your app and you’ll have an overwhelming app starring you in the face. It helps to have methodologies and pre-processors handy but even with these tools, CSS can easily balloon into a monster code-base that’s very hard to manage if not properly structured from the get-go.

In this guide, I’ll introduce you to a simple system i use to manage my CSS and how you can absorb it into your current front-end workflow. We’ll start with a brief introduction to methodologies and preprocessors and why you should pick up one if you haven’t already.

Why Do We Need CSS Preprocessors?

Whereas methodologies provide us with systems to manage our CSS, preprocessors such as SASS, LESS, and stylus provide tools to implement these in a way that is easy to understand and maintain. There are a few methodologies and preprocessors to choose from, but for this guide, I’ll be using the BEM methodology because it is relatively easy to pick up and it is very intuitive. I’ll also be using SASS as my preprocessor of choice because of its mass appeal.

Why Do We Need CSS Methodologies?

When it comes to writing CSS, I think it’s better to avoid selecting tags or even an element’s descendant because the HTML structure can change in the future. A better option is to split the HTML into independent components, style them with classes, and then compose them to achieve the desired interface, and here is where CSS methodologies come in. CSS methodologies are formal, documented systems for writing CSS in a way that allows us to develop, maintain and scale the front-end as a set of small, isolated modules.

CSS methodologies provide us with structures and mental models to manage CSS efficiently. With CSS methodologies, we can embrace the whole DRY (don’t repeat yourself) ideology easily because our CSS will be divided into isolated modules which makes styling a breeze and repetition kind of hard.

A Better Way To Structure CSS

The first step towards building a scalable and maintainable system is to group the primary values. Primary values are values that multiple parts of the system depend on, for example, colors, font families, and font sizes. If multiple components of the system rely on a value, it makes sense to isolate the value and store it somewhere and then reference that value from the dependent components instead of hard-coding the value into these components. So that in an event of a change, we will only update one part of our system and have the change reflected in all dependent components.

When grouping the primary values, we will store these values in CSS variables and reference these variables in our component. What we want to do is to pick out the primary colors and fonts and store them in CSS variables with explainable names. It’s easier if we have a UI to look at but if we don’t, then we’ll need to make these hard design decisions ourselves.

With everything we’ve said so far, our codebase should look more like this.

:root {
--main-accent0: hsl(165, 100%, 50%);
/* lighter version for hovers */
--main-accent1: hsl(165, 100%, 90%);
--headline-font: Ubuntu;

/* then in our call to action we can do like this*/
.button {
background-color: var(--main-accent0);
font-family: var(--headline-font);
&:hover {
background-color: var(--main-accent-1);

How To Structure CSS For Theme Switching

When it comes to themes (dark mode/light mode), there are a couple of ideas I know of: one way is to put the dark and light theme variables in their separate stylesheets and load them when the user needs them. I do not like this approach because the browser will have to fetch the themes from the server, and for servers with high latency, users with bad network speed, or even users using our app offline, our web app might not work smoothly.

My preferred approach is to have all the variables in one stylesheet, split them up into classes, and then toggle these classes depending on what mode we want to achieve. Here is what I mean.


.theme {
&__light {
--high-contrast-bg: hsl(194, 2%, 93%);
--high-contrast-text: hsl(194, 2%, 28%);
&__dark {
--high-contrast-bg: hsl(194, 2%, 48%);
--high-contrast-text: hsl(194, 2%, 98%);

.card {
padding: 20px;
background-color: var(--high-contrast-bg);
color: var(--high-contrast-text);
<!-- index.html -->
<body class="theme theme__light">
<div class="card">
<div class="card__header">
<div class="card__body">
<button class="theme-switcher">switch to <span class="theme-switcher__current-mode">dark</span> mode</button>

Here is a Javascript snippet to help us achieve that.

document.addEventListener("DOMContentLoaded", () => {
const theme = document.querySelector(".theme");
const button = document.querySelector(".theme-switcher");
const mode = document.querySelector(".theme-switcher__current-mode");
button.addEventListener("click", () => {
theme.classList.remove("theme__dark", "theme__light");
if (mode.innerText == "dark") {
mode.innerText = "light";
} else {
mode.innerText = "dark";

Thank you for reading this guide, I hope you’ve learned a thing or two. If you have a question or a suggestion for this guide, please don’t hesitate to send ’em in.




Explore the world of web technologies through a series of tutorials

Recommended from Medium

Why is Ruby on Rails A Pitch Perfect Back End Technology?

PROGRAMMER vs CODER | How I became a programmer

The 10 commandments of serverless

Eclipse IDE: hashCode() & equals()

#2 Writing our First Code — Python for Beginners

A red Python looking into the camera

Deploying AWS Lambda Functions On GKE using Knative and Triggermesh KLR

VPoS mining pool tutorial 6 — How to increase mining power

Web API that returns data to different sets of client based on the agreement with the organization.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Hilal Ahmad

Hilal Ahmad

A Software Engineer with 3 years of experience in Software development. Visit me at https://about.me/hilalahmad

More from Medium

Tailwind CSS will be my first choice amongst the others

Moodle H5P Styling (CSS)

The magic explained — HTML, CSS, JavaScript

Electric light bulb reacting to a hand

My New Spacecraft Browser Game with Vanilla JS