HSB Colors with Sass

Why do we need another color model you might ask? And it is a fair question, considering we already have RGB, HSL, and hex and we’re doing just fine. To convince you, I will tell you why HSB is awesome and how you can easily implement it in any Sass project.

Why HSB?

The HSB/HSV color model is actually a close kin of HSL. HSB stands for Hue, Saturation, and Brightness, the Hue component being equal to the one in HSL.

This easy-to-understand-at-a-glance factor isn’t present in RGB and hex — just try to imagine what rgb(173, 149, 128) or #ad9580 look like.

Also, if you need some level of transparency for a color, hex is no longer an option; you have to choose between RGBa and HSLa (and now HSBa).

HSB colors are also more readily available for use than HSL if you choose/get your colors from graphics software. Programs such as GIMP or Adobe’s Photoshop and Illustrator all prefer the HSB color model to HSL.

Having that foundation, let’s see how we can use HSB in a Sass project.

Building the Function

Adding support for HSB colors in your project is easy. We will define an HSB function, so that later we can use it just like HSL or RGB colors:

color: hsb(333, 84, 76)

This function will accept 3 or 4 parameters, the fourth one being the alpha channel, which we will set to 1 (fully opaque) by default:

@function hsb($h-hsb, $s-hsb, $b-hsb, $a: 1)

On the inside, the function will convert the HSB color to HSL (it’s the easiest conversion mathematically speaking). Sass will output the color in its Hex equivalent (or RGBa if the color has transparency) no matter the format you provide the input color in. Other preprocessors work the same way.

The Hue component doesn’t need to be converted, since it’s the same for HSB and HSL. To get the other components though, we need some math.

Deriving the Luminosity of the HSL equivalent to our HSB color is done with a simple equation:

The if statement is there for the proper behavior of the saturation, which starts to decrease once the lightness of the HSL surpasses 50%. Here is a more detailed explanation.

In the end, we simply return the new value:

@return hsla($h-hsb, $s-hsl, $l-hsl, $a);

Okay, now we have all 3 components: Hue, Saturation, and Luminosity. But our code isn’t flawless yet. Our function will fail if the third parameter (the Brightness, or $b-hsb) is 0 because we cannot divide by zero. Happily for us, having a brightness of 0 in HSB means that the output color will always be black, no matter what the other two parameters are.

Therefor, the best way to resolve this issue is to add a condition to our function that automatically outputs black if the brightness is zero:

A Final Note on Precision

Keep in mind that the color picker of Adobe Photoshop (and other graphics software) does some rounding when calculating the equivalent HSB of a certain Hex color. This happens because these different color models allow for different precision for its color components.

An example of the rounding issue is shown in the CodePen above, under .test-precision, where a hex color from Photoshop outputs rounded HSB values, and if you put these rounded values in an HSB to hex converter (for example the one we just built) we might get a slightly different hex color than the original (the difference however, is imperceptible).

If you play around with this awesome color converter you will see that the HSB/HSV equivalent of most hex and RGB colors doesn’t have all its components nicely rounded like we’re used to seeing in Photoshop. This is the tool I’m recommending if you happen to need precise colors or just want to avoid this rounding issue for Zen reasons.

Alexander is a front-end developer currently working at Telerik. The few years he spent studying anthropology and working in the usability domain help him not to forget that code should be written first for people and then for machines. He owns and maintains CSS PRE, a small site that compares the popular CSS preprocessors.