Relative Color Palettes with Sass

Ethan walks you through HSL color notation, then gets funky with color functions.

Building a color palette using Sass variables is nifty. It keeps all your color definitions in a single place. This is a useful reference and will prevent you from accidentally creating unneeded tiny color inconsistencies. It also makes your code a little more flexible: change the value of a color variable, and it changes everywhere it was used. Good code is flexible code.

But you can take your color palette’s flexibility further than color values in variables. What if you could build an entire color palette based off a single color? And what if you could change that single color to shift the entire color palette? Well you can, but how to best make use of this power is up for debate. More on that later. First, we need to talk about HSL color notation.

H/S/L?

In CSS, any color can be represented in several different ways. Let’s take #ff0000 as an example. This color is an intense shade of red. It can be written in a few different ways:

  • #ff0000
  • #f00
  • red
  • rgb(255, 0, 0)
  • hsl(0, 100%, 50%)

Using any one of these values as a color in CSS results in the exact same shade of red. In Chrome, Safari, and Firefox’s dev tools, you can cycle through these notations by holding shift and clicking the little box of color.

Example of holding shift and clicking the web inspector's color box

I want to talk about that last way of declaring color, because you might be less familiar with it. HSL stands for “hue, saturation & lightness.” It looks a little funky at first glance, but in my opinion, it’s the most intuitive way to write out a color. Here’s how it works:

Hue is the first value. It describes what the color is, written in degrees on a color wheel. 0 is red, 120 is green, and 240 is blue, 360 is looped back to red again. Any number in between results in a color between these reference points.

Saturation is the second value. It describes how intense a color is. 100% is a fully rich color, 50% is a little faded, 0% is fully grayscale.

Lightness is the third value. It describes how close to white or black a color is. 50% is right in the middle, 100% is fully white, 0% is fully black.

Compared to RGB, HSL is a more natural, human-readable way to describe color. It’s also much easier to transform from one color to another.

We know that hsl(0, 100%, 50%) is a rich red color. Now take a close look at the slightly different color, hsl(0, 50%, 80%). Comparing the two, we can see that the second one is the same hue, has less saturation, and more lightness. You can conclude that the second color is lighter and paler than the first color, just by looking at the differences in values.

Here’s the interesting part: the differences between these colors describes the relationship between these colors. And these relationships can be applied to other colors.

Subtracting the first set of values from the second, we see that there is 0 difference in hue, -50% difference in saturation, and +30% difference in lightness. If we apply these transformations to a rich blue color, we’ll end up with a lighter and paler lavender color. If we apply them to a rich green, we get a lighter and paler seafoam green.

Here’s what this looks like in action:

See the Pen Color Relationships (hard-coded) by Ethan Muller (@ethanmuller) on CodePen.

Getting Funky with Functions

Sass provides several color functions that let you transform colors in a few different ways. You pass them a color and receive a different color.

You can use color functions to shift a color’s hue. Or you can saturate/desaturate it. Or you can adjust a color’s lightness. You can even chain these functions, so that you can apply multiple transformations to a color before using it as a value.

Using a combination of these color functions, we can wrap up any of these color transformations into a single reusable function. That means we can use a color function to represent the relationship of any two colors.

Here’s the example from above, but refactored using a function that automates the color differences:

See the Pen Color Relationships (functional) by Ethan Muller (@ethanmuller) on CodePen.

And this is where it gets funky. Now that we’ve automated these transformations with functions, we’re able to put together more interesting things.

So far, we’ve only dealt with one transformation from a base color. Pass in a red; receive a lighter/paler red. But there’s no reason we’re limited to a single transformation. We can pass one color to many different functions to get many different colors. We can build up a palette of functions. This serves as a dynamic palette of colors, all based on a single color. And changing the base color results in all colors shifting relatively to that color change.

Here’s what that looks like in action. I created one floaty cube graphic using various shades of blue. Then I factored all those blues into functions. It’s made up of four colors: one base color, plus three variants on that base. Since all the color variants are functions, we can plug in a different base color to get a recolored version of the original. And we can do that a bunch of times. With a bunch of different colors. Then one thing leads to another, and you’ve got a floaty cube rainbow on your hands.

See the Pen Floaty Cubes (w/ relative color palettes) by Ethan Muller (@ethanmuller) on CodePen.

Let the Robot Do the Work

It’s worth it to take the time to check out HSL notation, pick it apart, and understand how it works. Doing math by hand is cool and all, but in my book, making a computer do math for you is cooler.

SassMe is a tool that automates this color conversion. You plug in a starting color, then tweak the color’s hue, saturation, and lightness via sliders. Its output is a chain of Sass functions that transforms the original color using Sass’ built-in color functions. Transforming colors with this tool is much more intuitive than doing the arithmetic manually. Since you can see colors transform in real-time, you can explore more freely and end up with better results.

Not using Sass? First of all, I’m surprised you’ve read this far into the article. Second of all, ColorMe does the exact same thing, sans Sass! It uses the upcoming CSS Level 4 color function to transform colors. At the time of this writing, no browsers support these functions yet. However, you can still use something like cssnext to process your styles before they even touch a browser, which means you can start using it today. Welcome to the future.

How Should I Use This, Anyway?

You can base your entire website’s color palette off a single color using this technique, but I wouldn’t necessarily recommend it. I don’t see much benefit in that, especially when you consider the tradeoffs in code readability.

Where this is useful is generating mini color palettes. When you design a module once, it’s a breeze to create dozens of color variations for that module. This could work great if your website has multiple themes. This technique also enables you to play with colors more freely and iterate on designs much more quickly than you’d be able to in a tool like Photoshop or Sketch. If you’re a “design in the browser” type of person, this could help you come up with designs you wouldn’t have found otherwise.

And I’m just spitballing here. I bet you’ll be able to find other neat ways to use this technique. Just be sure to write some nice thorough comments to explain what’s going on. Also, we’d love to hear about it over on Twitter! Use #relativeHSL to show off anything cool you’ve built using this idea.