How to Create a Dark Mode in Sass

TLDR: Scroll down to “Step 1.”

Why doesn’t Sass have better support for color theming, since it’s all the rage?

Let’s face it, dark modes are trending.

Maybe it’s because the amount of hours per day we spend staring at a screen is only going up.

Maybe it’s because we are using our screen-based devices in low-light environments more and more (in a car at night, in bed, in a hospital command center).

Definitely it’s because Apple did it.

Once upon a time as a part of my job as a UI Designer I was assigned to “make a dark mode” (more on that and why it maybe wasn’t the best way to approach here.) I eagerly googled “how to color theme sass,” fully expecting to be able to do something along the lines of this:

//how NOT to do color theming in Sass, unfortunately$background;if ($theme == 'dark') {
$background: #333;
} else {
$background: #ebebeb;
.my-div {
background: $background;

I don’t know if this speaks to my inability to understand Sass, or to Sass’s inability to anticipate developer needs, but the fact is Sass compiles to good ole css — it’s a preprocessor and not a full-fledged language. Therefore it can’t just swap all your variables on the fly after it is already compiled.

The current prominent approach to theming in Sass

Fortunately there are some excellent ideas on the web for how to solve this problem. They all boil down to more or less the same thing:

  1. Assign a toggle-able “root” theme class to the body element (or app root, for React land) like theme--light.
  2. Write a fancy Sass method that uses the built-in Sass map__get function to iterate through an array of themes (more on this later).
  3. Call your fancy method when you have a color that you want to use.

It will compile to something like this:

.theme--dark {
.my-div {
background: #333;
.theme--light {
.my-div {
background: #ebebeb;

Isn’t there a better way to do this?

It was hard for me to come to terms with the fact that you can’t just switch out the value of variables on the fly. It was hard on my architect, too. We were pretty sure there had to be a better way.

Well. In my research and brainstorming, I found three viable approaches to theming a web app with (or without) Sass:

  1. Write a whole new stylesheet for your dark mode. Oof. This is quite ugly because it makes for a lot of code, and your engineers will have to update two stylesheets every time something changes!
  2. Use some clever, super globalized styling like this. This could work for you if your website is super simple, and you aren’t picky about the result (both not my situation).
  3. “The current prominent approach to theming in Sass” I just mentioned. Guess which one I picked.
My notes from debating methods for color theming when I was assigned to create a dark mode for a very complex interactive dashboard (built with some very old legacy code, and no Sass)

My version of the current prominent Sass method


  1. Developer friendly. Love ‘em to death, but most of the engineers I currently work with absolutely hate writing css.
  2. Scalable. I am working in a (scary) HUGE platform of enterprise solutions with a lot of preexisting styles, a team of 100+ engineers, and naturally, a range of technologies.
  3. Minimized margin of error. See #1. I don’t want anyone to have to write a string at any point.

Ok, here goes. If you’re scrolling through this waiting for the part where I tell you how to do the thing, stop here.

My method is largely based on an excellent article written by Dmitry Borody but tweaked to meet my above goals.

I implemented theming on my personal website. You can view the source code here.

Step 1. Make your themes. Fun!

I have everything in a Sass partial called _color-themes.scss.

You can define pretty much whatever you want here. Note that I have a different version of my logo for each theme, and also that I am passing in a gradient for my background on my dark theme, but not the light theme.

I am passing in Sass variables, but you could use hex values.

Step 2. A fancy mixin

Here’s what’s happening here:

  • The themed mixin iterates through all of your $themes and for that theme defines a global Sass map called $theme-map
  • It takes the blurb of code you entered (more on that in Step 3) and outputs it with the theme-defined values in the place where you used the t function.

It outputs the themed blurb using @content

Step 3. The “more on that in a sec” part: how to call the theming function and mixin from within your stylesheets

Each time you want to use a theme, call the themed mixin with @include themed() and inside it use the t() function around your key.

I was worried about having developers write strings ever time they wanted to use a variable, so I added shortcuts at the top of my _color-themes.scss file that simply output strings that match the keys in my $themes object.

$bg: 'bg';
$card-bg: 'card-bg';
$text: 'text';
$text-secondary: 'text-secondary';
$link: 'link';
$hover: 'hover';
$logo: 'logo';
$brand-blue: 'brand-blue';
$brand-red: 'brand-red';
$border: 'border';

These are what I’m passing into @t like color: t($text); but I could also do color: t(‘text’);.

Step 4. Toggle the theme!

Here is how I did it on my website which I built in React.

Your outputted css should follow this format!

.theme--dark {
.my-div {
background: #333;
.theme--light {
.my-div {
background: #ebebeb;

See my example here

As mentioned earlier, I implemented theming on my personal website. You can view the source code here. If you have any feedback or ideas for improvement I’d love to hear them!

Additional mixins

If and when I implement this in an enterprise environment, I plan to leverage @extend to create reusable blocks of the most common color combinations in the hopes that this will help minimize margin of error:

%card-colors {
@include themed() {
color: t($text);
background: t($card-bg);
border: t($card-bg);

This is still not that great.

At the end of the day, there are some problems with this method:

  • Room for error
  • No support for white-labeling (like, at all)

Dear Sass,

Please build support for theming into your framework!

❤ , me



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