HSLuv vs. HSL

HSL CIELUV LCh HSLuv HPLuv
Lightness Relative Absolute Absolute Absolute
Saturation* Relative Absolute Relative Absolute
Saturation range Percent Undefined Percent Percent
Saturated colors Yes Yes Yes No
Hue uniformity Poor Good Good Good
* Saturation and chroma are distinct concepts

Overview

HSL
CIELUV LCh

The dips in the graph represent impossible colors (such as dark saturated yellow). CIELUV LCh doesn't warn you about them, making it unsuitable for generating colors.

HSLuv

HSLuv preserves the lightness and hue components of CIELUV LCh and stretches its chroma so that every color has the same range, defined as a percentage.

HPLuv

HPLuv takes as many colors as it can from CIELUV LCh without distorting the chroma. As you can see, the resulting color space is smooth, but only pastel colors can be included.

Chroma

HSL
CIELUV LCh

The chroma component of CIELUV LCh is absolute. Unlike HSL's saturation you can effectively use it to compare two different colors.

HSLuv

Both HSL and HSLuv have a distorted chroma map, this is a trade-off of their convenient shape. Admittedly, HSLuv's chroma has more sudden shifts.

HPLuv

Lightness

HSL

This is why HSL is useless for working out contrast. The actual lightness varies drastically between hues.

CIELUV LCh
HSLuv

For this demo I am using CIE's definition of lightness. Both CIELUV LCh and HSLuv use this component, so their picture is an even gray.

HPLuv

Let's try to generate some random background colors:

function randomHue() {
  return Math.floor(Math.random() * 360);
}
$(...).css('background-color', HSL.toHex(randomHue(), 90, 60));
$(...).css('background-color', hslToHex(randomHue(), 90, 60));
Lightness: 60%
Lightness: 60%
Lightness: 60%
Lightness: 60%
Lightness: 60%
Lightness: 60%
Lightness: 60%
Lightness: 60%
Lightness: 60%
Lightness: 60%
Lightness: 60%
Lightness: 60%

HSLuv's uniform hue means random colors will be truly random. Iterating over colors will also produce better results.

$('#rainbow-hsluv div').each(function(index) {
  $(this).css('background-color', HSL.toHex(index * 36, 90, 60));
});

$('#rainbow-hsl div').each(function(index) {
  $(this).css('background-color', hslToHex(index * 36, 90, 60));
});