Implementing Dark Mode With SASS

My site officially has dark mode and it automatically responds to visitors’ system preferences! I held off on implementing it for a while because I figured it would be a lot of work. Turns out it only took 30 minutes and 5 lines of code.

Here’s how I did it.

Implementation

This is all it took to enable dark mode. A CSS media query and a SASS mixin.

@media (prefers-color-scheme: dark) {
  body {
    @include dark-mode;
  }
}

Using a SASS Mixin

Ok so what’s hidden in that dark-mode mixin?

The truth is there are about 50 lines of code hidden in the mixin. It’s a bunch of style overrides setting the dark theme. Here’s an excerpt:

@mixin dark-mode {
  background: $color-charcoal;
  color: $color-white;
  a {
    color: $color-white;
    &:hover {
      color: $color-blue;
    }
  }
  .meta__primary {
    color: $color-white;
  }
  .meta__secondary {
    color: $color-white;
  }
  .tags__item {
    border-color: $color-mid;
    color: $color-white;
    &:hover {
      color: $color-white;
      border-color: $color-blue;
    }
  }
}

The cool part is that these are 50 existing lines of code. My original site design included some light and some dark pages, depending on the type of content being served. Previously, pages with a lot of text (blog posts) were white and pages with a lot of media (case studies) were dark.

I was using a body class to apply these style overrides to pages selectively:

<body class="dark-mode">
  <!-- Site content here -->
</body>
.dark-mode {
  @include dark-mode;
}

I was delighted to find that including this existing mixin inside a media query is all it took to enable dark mode:

@media (prefers-color-scheme: dark) {
  body {
    @include dark-mode;
  }
}

The Power of CSS

CSS gets a lot of hate, but this is one of those situations where the cascade proved incredibly helpful and efficient. For a small, mostly-editorial site like mine, adding some simple overrides works great.

This approach also plays nice with external libraries.

I was able to add a dark theme for syntax highlighting by including a new Pygments theme in the media query. Easy.

@media (prefers-color-scheme: dark) {
  body {
    @include dark-mode;
    @include monokai-dark;
  }
}

Your Turn

You probably you don’t have a convenient file of dark mode overrides sitting around for your site. Still, keep in mind that it only took 50 lines of color customization to make this happen. If your site has a lot of text, it’s worth adding dark mode to improve your nighttime UX.