DEV Community

Tom Österlund
Tom Österlund

Posted on

Light- and dark mode CSS, the easy way

One of the never-ending tech-battles on social media right now is the battle between light- and dark mode. Everyone knows this is ultimately a matter of good and evil. Light side of the force vs. dark side of the force.

Luke vs Darth Vader

Whether you prefer light mode or dark mode: as a web developer, there is a high chance you need to know how to support both modes. When building the Schedule-X calendar, I used a method for supporting both modes with very low effort. And here's how you can do it too.

Step 1: define all colors as CSS custom properties

Firstly, you need to define all the colors you want to use in CSS custom properties. You can create a color.scss file, looking something like this:

:root {
  --color-primary: #6750a4;
  --color-on-primary: #fff;
  --color-primary-container: #eaddff;
  --color-on-primary-container: #21005e;
  --color-secondary: #625b71;
  // ... and so on
}
Enter fullscreen mode Exit fullscreen mode

Now, if you're using SCSS like I do, you might be tempted to write these colors as SCSS variables, like $color-primary. But don't! These SCSS variables only exist at compile-time, and won't be around to be altered at run-time where we will need them later.

Step 2: using the CSS custom property-colors everywhere in your application

If you want to successfully use this method, you need to stick consistently to this rule. Wherever you use colors in the application: use them through CSS custom properties. Even if it's "just" a simple border color, don't cheat; border colors typically need a very different nuance in dark mode than they do in light mode! So for example:

.my-rule {
  border: 1px solid var(--color-neutral);
}
Enter fullscreen mode Exit fullscreen mode

Step 3: Create a single dark-mode rule

In the same file where you defined your colors for light mode, you can add a rule for the selector .is-dark, like this:

.is-dark {
  --color-primary: #d0bcff;
  --color-on-primary: #371e73;
  --color-primary-container: #4f378b;
  --color-on-primary-container: #eaddff;
  --color-secondary: #ccc2dc;
  // + other properties
}
Enter fullscreen mode Exit fullscreen mode

Now what does this rule do?

Basically, it just means, that whenever you slap the class name is-dark onto an element, the dark mode colors will start being applied to everything inside of that element - as long as you consistently used the custom properties for defining color.

And that's it! Creating a dark mode for your web project does not have to be hard.

If you want to play around with the concept yourself, here's a brief demo for how it works on Codepen:

Image of Timescale

Timescale – the developer's data platform for modern apps, built on PostgreSQL

Timescale Cloud is PostgreSQL optimized for speed, scale, and performance. Over 3 million IoT, AI, crypto, and dev tool apps are powered by Timescale. Try it free today! No credit card required.

Try free

Top comments (0)

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more