hwb() – a color notation for humans?
- Published at
- Updated at
- Reading time
- 3min
CSS color handling seems to be on an evolutionary roll lately. Call me old-school, but I still primarily use RGB-based color notations (#aabbcc
and sometimes rgb(100, 120, 140)
).
hsl()
is cross-browser supported for ages, fancy stuff like lab()
and lch()
is in the making (I've no clue what these are for...), and there's finally a syntax on its way to converting one color definition into another one.
But have you heard of hwb()
? The color notation is defined in the CSS Color Module Level 4 spec, and even though the spec is still in draft and being worked on, hwb()
is defined for years (Stefan Baumgartner blogged about it already in 2014)!
Browsers didn't implement it over all these years, ignoring that this color notation should be easier for humans to work with according to the specification! But now, it seems the color notation's time has come. Safari 15, Firefox 96) and Chrome 101 implement hwb()
(see the up-to-date compatibility data below 👇).
101 | 101 | 101 | 96 | 96 | 15 | 15 | 19.0 | 101 |
I'm human (yay!) and up for easy stuff, so let's have a more detailed look and see if the bold claim holds!
hwb
stands for hue (a color angle), whiteness (a percentage) and blackness (a percentage) – hwb(10deg 10% 10%)
. Pick a color and adjust its lightness by adding Black or White.
If hue
is a unitless <number>
, it is interpreted as degrees.
The entire concept and possible colors can be visualised in a triangle spanned by Black, White and the color of choice.
It surprises me that the spec claims that many color pickers adopt the hwb
notation and the related triangle color picker because I haven't seen this approach to color picking in ages. 🙈
The idea seems simple, but I have to admit, hwb()
confused me.
Sure, pick a color via its hue angle and make it lighter or darker. Easy-peasy, but what happens when one adds White and Black? How could I define White and (!) Black for a color angle, and aren't Black and White evening each other out? What happens if a color includes 100% Black and(!) 100% White?
I built a quick prototype to understand this "easy color notation" and answer all my questions. 👇
.preview {
background: hwb(222deg 25% 10%);
}
Adding White and Black to a color affects its saturation. Suppose you add the same amount of White and Black to a color, the color tone stays the same, but color loses saturation. This works up to 50% White and 50% Black (hwb(0deg 50% 50%
)), which results in an achromatic color.
If the sum of Whiteness and Blackness exceeds 100%, the values are normalized to add up to 100%. The relative ratio between Whiteness and Blackness is kept intact. hwb(0deg 100% 100%)
results in hwb(0deg 50% 50%)
, hwb(0deg 300% 100%)
becomes hwb(0deg 75% 25%)
, and so on. All colors stay achromatic.
If you add either 100% of Whiteness or Blackness to a color, the result is pure White or Black.
Similar to rgb()
and hsl()
you can also apply an optional opacity parameter to hwb()
(hwb(194 0% 0% /
or hwb(194, 0%, 0%,
).
So, the main question remains. Is hwb()
more human-friendly than other color notations?
I'm not sure... hsl()
is pretty handy for controlling a color's saturation or lightness. And even though I understand that the Whiteness/Darkness approach might be more logical ("Just add a little bit of black to a color to make it darker"), I guess I'll prefer the color notations we already have. 🤷♂️
But hey, it was fun to build this quick prototype (which might be the reason for this article in the first place). 🙈
Join 5.5k readers and learn something new every week with Web Weekly.