don’t use hsl for anything

Making websites usually involves COLORS (they’re all the rage these days!).

You’ll no doubt find HSL easier to work with as a developer, since it was designed to manipulate colors more directly. However, just because it’s easy to edit doesn’t mean it’s a superior format. In fact, quite the opposite.

HSL is missing a lot more than it gives

There’s not a 1:1 conversion between HSL and RGB. In one sense this is obvious, because HSL’s appeal is that it’s not RGB. But in another sense, just how different they are can often be overlooked, and you’d be forgiven for not realizing HSL is as bad as it is.

format formula values spread
RGB 256 ^ 3 16,777,216 100.0%
HSL 360 ✕ 100 ✕ 100 3,600,000 21.5%

Just comparing the possible values, HSL is missing almost 80% of RGB’s. But if throwing away 80% of colors weren’t bad enough, it’s actually worse! Not every HSL value maps to a unique RGB color, and there are multiple ways to express the same color in HSL. For example, when saturation is 0, HSL has 36,000 different values that generate only 100 grays. When you remove all the duplicates, HSL is missing closer to ~85% of RGB’s colors (source). And when is an 85% loss in quality ever acceptable?

When is an 85% loss in quality ever acceptable?

HSL can accept decimals, though! you may think. However, when you try to manage HSL values with a single decimal place, it skyrockets to 3.6 billion possible values and becomes a barren wasteland of mostly-duplicated colors. Since now most adjustments won’t end up changing the color at all, it means using HSL with decimals makes it worthless.

So back to our original premise: when storing colors, HSL is a terrible format to use because it’s missing so much of the RGB colorspace. And attempting to fill in those gaps results in mostly-useless values.

The “L” stands for “Ludicrous”

If missing colors weren’t bad enough, the colors that are there are widly distorted. It’s assumed that the L in HSL designates the lightness of a color, right? Well, in theory, yes, but in practice…

the dips in the graph represent impossible colors
via @sitnik

Turns out lightness as expressed in HSL is really useless when translating from one hue to another. Compare all these values that have 50% lightness in HSL, when compared to their grayscale equivalents:

Calculated using better-color-tools

Not even close. Yellow is significantly brighter than the other colors! While L does have a purpose, it’s usually not what people think.

HSL isn’t even that good of an interface

In case you’re tempted to store color values as RGB, then convert to HSL, there’s a better interface: the CSS color() function Though it’s been teased for years, and is still not available in 2021, when it finally is released will provide all the usefulness of HSL and then some. And it even lets you use  ALL  THE  COLORS  of RGB.

And until that’s released, please just use Sass’ color function today. You can run all valid CSS through Sass, it only takes a few milliseconds, and it lets you perform more complex color manipulation without any of HSL’s limitations.

I know that 16.7 million colors sounds like a lot, but it pales in comparison to the actual number of colors the human eye can perceive (for goodness’ sake; we can’t even recreate brown digitally!). So please don’t reduce the palette any further than necessary just because it makes a button hover effect easier to manage.