Replicating preprocessor color functions with plain old CSS

17 May, 2014

I was ruminating on Sass’ lighten and darken functions today morning and wondered whether there was a way to do this via native CSS. I also remembered that I haven’t ever used HSL to define colors in my stylesheets and wondered whether this was the solution. I generally use the hexadecimal notation and also RGBA aplenty when I need to alter the transparency of a color.

However, HSL and HSLA have landed up being the revelations of today’s morning. It’s close to midnight and I’m close to being done with this article. And I’m definitely considering using them to define colors in future projects.
P.S. Just like RGBA, both HSL and HSLA need a fallback for IE8, if you’re supporting it.

Let’s do a quick recap on colors in CSS to get some foundation:

There are 4 ways to declare a color in your CSS stylesheet:

1) Keyword

color name

E.g. black, olive, firebrick

It’s good to check browser compatibility, although modern browsers support a whole slew of keywords for color names.

See the W3 spec for basic color keywords: and for extended color keywords, which are supported by modern browsers:

2) Hexadecimal notation or Hex triplet:


E.g. black is #000000, olive is #808000, firebrick is #b22222

Possibly the most common way to declare colors in CSS. Consists of a # character generally followed by 6 characters, where each pair represents the red, green and blue value. Uses numbers 0 – 9 and letters A to F to represent the color.

However, there is a 3 character shorthand form, which can be used when each pair consists of the same digit.

E.g. Black can be written as #000 instead of #000000 and red as #f00 instead of #ff0000.

3) RGB triplet or decimal notation:

rgb(r, g, b) or rgb(%, %, %)

Expresses a red, green and blue component, each generally within the range of 0 – 255 or percentages between 0 – 100%.

E.g. RGB with parameters in integers:
Black is rgb(0,0,0), olive is rgb(128,128,0), firebrick is rgb(178,34,34)

E.g. RGB with parameters in percentages:
Black is rgb(0%,0%,0%), olive is rgb(50%,50%,0%), firebrick is rgb(70%, 13%, 13%)


hsl(hue, saturation, lightness)

E.g. black is hsl(0, 0%, 0%) , olive is hsl(60, 100%, 25%), firebrick is hsl(0, 68%, 42%)

Check out this color wheel. Think of it as a pretty rainbow circle and you’ll never forget it.

Let’s look at the three parameters of hsl:

Hue, the first parameter is simply an angle measured in degrees on the color wheel.

0 degrees represents red
60 is yellow
120 is green
180 is cyan
240 is blue
300 is magenta

Isn’t that sweet and simple?

Hue is represented by an integer.

Saturation, the second parameter is represented by a percentage between 0 and 100, where 0 is some variant of grey/black and 100% is full saturation of the color.

Lightness, the third parameter is represented by a percentage between 0 and 100, where 0 is black and the darkest, 100% is white and the lightest and 50% is average.

This post doesn’t go into the details of the alpha channel, because if you are familiar with RGBA, HSLA follows the same principle, where the last parameter declares how transparent the color is, and even allows a float value (decimals) between 0 and 1.

Let’s screw around with HSL now:

Look at the color wheel again:

I want red #f00 represented as hsl:
color: hsl(0%, 100%, 50%)

0 corresponds to the hue, 100% is full saturation and 50% is an average.

I want firebrick #b22222 represented as hsl:

color: hsl(0, 68%, 42%);

As you see, the hue is still red, but the saturation and lightness are both reduced. It just makes sense.

What’s so cool with HSL?

  • - Well, for starters I can look at the color wheel and figure out the color I want. It looks pretty intuitive to me.
  • - It should be pretty easy to get a contrasting color by just looking at the color wheel to see the degree on the opposite side.
  • - I can adjust the shade of the color, and I can’t do this any other way in CSS. I can replicate some preprocessor color functions.

Hence, I could potentially lighten, darken, increase or decrease saturation, adjust hues and provide a contrasting color quite easily.

Let’s look at some basic Sass color functions and ways to replicate this with native CSS.

Our basic example contains no variables and uses the firebrick color, whose HSL is (0, 68%, 42%) and HEX value is #b22222.

Firebrick color

Lighten firebrick by 10%
Sass: lighten(#b22222, 10%)
CSS: hsl(0, 68%, 52%)

Both result in #d83131

The CSS way simply increases the percentage of lightness, i.e. the third parameter of HSL by 10.

Darken firebrick by 10%
CSS: hsl(0, 68%, 32%)
Sass: darken(#b22222, 10%)

Both result in #891a1a

The CSS way decreases the percentage of lightness, i.e. the third parameter of HSL by 10.

Saturate firebrick by 10%
CSS: hsl(0, 78%, 42%)
Sass: saturate(#b22222, 10%)

Both result in #bf1818

The CSS way increases the percentage of saturation, i.e. the second parameter of HSL by 10

Desaturate firebrick by 10%
CSS: hsl(0, 58%, 42%)
Sass: desaturate(#b22222, 10%)

Both result in #a92d2d

The CSS way decreases the percentage of saturation, i.e. the second parameter of HSL by 10

Adjust the hue by 10%
CSS: hsl(10, 68%, 42%) Sass: adjust-hue(#b22222, 10%);

Both result in #b43b22

The CSS way alters the hue degree, i.e. the first parameter of HSL by 10.

So the next time you use a pre-processor to carry out some manipulations on your colors, remember you can do some of it with good ol’ CSS, the HSL way :)


I’m considering moving to hsl for upcoming projects, especially if they don’t need IE8 support.

If you wish to use HSL and HSLA, do keep in mind:

  • - Please declare a fallback color if you need to support IE8
  • - Photoshop has a something called HSB (Hue Saturation Brightness), which does not correspond to HSL.
    Here are some good solutions to this:
    1. Check the amazing Seriously, this website is the bomb and converts virtually anything to anything. I love it.
    2. Declare the colors as you wish and then fire up dev tools in Chrome. Click the floral looking gear icon and under elements in General settings, show the color format as HSL. Then you can inspect element and get your HSL values for colors.

    Related tags: CSS-Colors, HSL, RGBA

    comments powered by Disqus