November 13, 2018

Switchable Color Schemes in SASS

Written by Haley Troyer

Share on LinkedIn

The Problem

We recently worked with a client who had a desire to switch their website’s theme colors to show their support for different events and holidays throughout the course of the year. They wanted it to be as simple as choosing their color scheme from an administrative section of their website, so we needed to build something that didn’t require any code pushes to achieve.

Ideal Solutions:

1. Setting/changing inline CSS based on a configurable color code

This would have been a nice solution because it would have supported any number of color combinations. However, this solution didn’t work for us because of how large and complex our client’s site was (there were too many elements on the site that depended on the color change). There are user experience implications to this solution as well, since it would allow an admin to select colors with poor contrast (an accessibility no-no) or colors that are, simply put, ugly.

2. Setting/changing a SASS variable based on a class

This would have been our most ideal solution… if it were possible. Sadly, SASS does not support changing the scope of variables (cue sad trombone).

3. Using CSS variables to change color values based on a class

CSS variables, a relatively new concept, does allow us to change the scope of a variable based on a class or component; however, our client required support for Internet Explorer, which does not support new CSS variables. That, coupled with the more verbose and less human-readable CSS variable syntax (we’re used to SASS), drove us away from this solution. 

Our Actual Solution:

1. Create a SASS mixin for the css property that should change

For this example, we’ll use a mixin that supports changing text color, but you can create a mixin for any css property that should change based on the selected theme (such as background-color, border-color, etc.)


@mixin text-color() {
  color: red;
}

If you need to swap more than one color value, you can add a parameter to your mixin that denotes the color that will be swapped.


@mixin text-color($color: primary) {
  @if ($color == primary) {
    color: red;
  }

  @if ($color == secondary) {
    color: blue;
  }
}

You can also add any other parameters that your mixin might require (such as hover colors):


@mixin text-color($color: primary, $effect: none) {

  @if ($color == primary) {
    color: red;

    @if ($effect == hover) {
      &:hover {
        color: darkred;
      }
    }
  }

  @if ($color == secondary) {
    color: blue;

    @if ($effect == hover) {
      &:hover {
        color: darkblue;
      }
    }
  }
}

2. Add “schemes” to your mixin

This is as simple as setting the colors to be used for each body class. The downside to this approach is that all schemes need to be added up front (and any that need to be added later on will require a code push). Our client only required a few defined color schemes anyway, so this wasn't an issue for us.


@mixin text-color($color: primary, $effect: none) {

  @if ($color == primary) {
    color: red;

    @if ($effect == hover) {
      &:hover {
        color: darkred;
      }
    }

    /* This class denotes a color scheme */
    .dark-theme & {
      color: gray;

      @if ($effect == hover) {
        &:hover {
          color: black;
        }
      }
    }
  }

  @if ($color == secondary) {
    color: blueviolet;

    @if ($effect == hover) {
      &:hover {
        color: indigo;
      }
    }

    /* This class denotes a color scheme */
    .dark-theme & {
      color: blueviolet;

      @if ($effect == hover) {
        &:hover {
          color: indigo;
        }
      }
    }
  }
}

3. Call your mixin wherever color swapping is needed

Whenever you encounter an element that should respect your color scheme choice, just call your mixin rather than using the native css property. In our case, instead of using “color,” we’ll use our text-color mixin.


h1 {
  @include text-color();
}

a {
  @include text-color(secondary, hover);
​​​​​​​}

And voila! Now, anytime the color scheme class gets added to your HTML, any element using this mixin will change its color to match. For our client, we also built a theme setting in Drupal that had a radio button for each supported color scheme. Changing this setting changes the class on our HTML body element, which corresponds to the classes used on our mixin. This allows our admin to simply select a new option to change the site’s color scheme!

We'd love to chat about your next web or application project!