HSL over RGB (and hex)

Color pencils of different lengths on a table

The best color in the whole world is one that looks good on you.

Coco Chanel

Which is better, HSL, RGB or hex? In this blog post, I will be exploring each of the common color representations in CSS.

Representing the colors of the rainbow

There are various ways to represent color in CSS:

These are just a few, but these are the only ones I care about.

The problem with RGB and hex

I've always used hex values when writing colors in code. Out of all the color representations, it's the shortest:

.rgb {
    color: rgb(250 142 50);
}

.hsl {
    color: hsl(28 95% 59%);
}

.hex {
    color: #fa8e32;
}

Technically, it was created to be the shortest; hex values are RGB values in the hexidecimal format. The hexidecimal format is usually shorter to write than its binary or octal counterparts, so I could see why it is used for representing color:

The number 245
Value in binary 11110101 (8 digits)
Value in octal 365 (3 digits)
Value in hex F5 (2 digits)

But are hex values the best representation simply because they are shorter?

Take for instance, what color do you imagine when you see #ff8cab or #d0bdf0? Of course they are the shorter hex values but what can we as humans make of those values?

Or, using RGB, what colors does rgb(194 33 205) or rgb(93 161 247) bring to mind? Would you know that #eaed20 and rgb(234 237 32) are the same color?

As you can see, hex and RGB aren't human-readable; they require a machine to visualize. Is there a way to write colors in a way that can be visualized but us mere humans?

HSL to the rescue!

HSL solves our readability problem. How? I saw the solution in a Stack Overflow answer where they illustrated a color wheel:

Color wheel

NOTE: As corrected in the original Stack Overflow answer, the angle for blue here should be 240°, not 270°.

HSL stands for Hue, Saturation and Lightness.

Hue is a pure color without tint or shade like red, green, blue etc. Its value is represented in degrees, from 0 to 360.

Saturation is how much hue is visible. Its value is represented as a percentage; 0% saturation displays dull gray, 100% saturation displays the hue.

Lightness is how much whiteness is visible. Its value is represented as a percentage (like saturation); 0% lightness displays pure black, 100% lightness displays pure white.

Saturation and lightness

Using this knowledge, its a lot easier to visualize colors from looking at its HSL value. Take for instance, the color #e9520c:

Type Value
Hex #e9520c
RGB rgb(233 82 12)
HSL hsl(19 90% 50%)

If we wanted to mix a bit of white into the color (#f7996e), the new value would become completely different:

Type Old value New value
Hex #e9520c #f7996e
RGB rgb(233 82 12) rgb(247 153 110)
HSL hsl(19 90% 48%) hsl(19 90% 70%)

The only exception is the HSL value, which changed merely from hsl(19 90% 48%) to hsl(19 90% 70%). As a human (at least from the last time I checked), I can easily tell that the new color is the same, just slightly darker; this analysis is impossible with the equivalent hex and RGB values.

I could also analyze the color as a whole: 19 represents 19°, which evaluates to orange from looking at the color wheel; 90% means that the color is closer to the hue than it is to dull gray; 48% means that the color is closer to black than it is white.

Reading colors this way makes me feel like a color guru!

Bonus feature: relative values in CSS

CSS allows for the use of relative values to determine HSL values:

hsl(from green h s l / 0.5)
hsl(from #0000FF h s calc(l + 20))
hsl(from rgb(200 0 0) calc(h + 30) s calc(l + 30))

What this means is that you can get the h, s and l from any color and manipulate it. For instance, for the first example:

hsl(from green h s l / 0.5)

Green would have the HSL value of hsl(120, 100%, 25%). This means that h would evaluate to 120, s to 100 and l to 25. Those values can be manipulated with CSS functions like calc() to tweak values. For instance, if I wanted the green color to have 20% less saturation, I could do this:

hsl(from green h calc(s - 20) l / 0.5)

Pretty intuitive!

The CSS color wheel

Creating a color wheel is easy in CSS with our knowledge of HSL:

The CSS code?

.css-color-wheel {
    width: 250px;
    aspect-ratio: 1;
    margin: 0 auto;
    clip-path: circle(closest-side);
    background: conic-gradient(
      hsl(360 100% 50%),
      hsl(315 100% 50%),
      hsl(270 100% 50%),
      hsl(225 100% 50%),
      hsl(180 100% 50%),
      hsl(135 100% 50%),
      hsl(90 100% 50%),
      hsl(45 100% 50%),
      hsl(0 100% 50%)
    );
}

Simple! In summary, CSS is awesome!

The bottom line

Ditch RGB and hex in CSS; use HSL. You make your code so much more readable and the values become more familiar with continuous use.

Further reading

If you would like to reply to or comment on this blog post, feel free to email me at efe@mmhq.me.