How do we see colors? How can we “define” them in a generic way? How do we compare them?

Well, this isn’t an easy topic.

Color vision

There are (in most cases) 3 types of cone cells in the human eye that helps us to see colors.

Human color vision

Pretty easy to see, why we mostly use yellow-green for visibility clothing.

Their response “function” overlap, it’s more efficient for our visual system to record the differences between the response of the cones, rather than the response of each. With this opponent color theory we can build a 3D space, where we can place individual colors:

  • black vs white (lightness, L)
  • red vs green (a)
  • blue vs yellow (b)

But this isn’t that simple, about 5% of caucasian people have color vision deficiency (~color blindness), which means they either cannot really differentiate colors on one of the color axes (or both, then they are color blind, indeed). Red-green CVD is the more common (99% of all).

And that’s just the difference in the eye, our brain has also an important role in the color vision, so some of us are capable seeing impossible colors, too.

Non-human color vision

And that’s just humans.

Most mammals have only two cones, so cats, dogs, cows, elks and such have very similar color vision as people having red-green CVD.

Dog color vision

Have you ever wondered why tigers are orange striped? Growing orange pelt is much easier than green, and they prey see them as the same color, so they are basically comouflaged in the forrest.

Also got pretty clear why hunters use orange visibility clothing…

There are also animals that can see very different or much more colors than us (and we cannot even imagine what they might see). Bees for example have 3 types of cones too, but they respond to green, blue and UV wavelengths. Birds have 4 cones, yellow, green, blue and UV.

Bee/bird color vision

Bird color vision demo

… and even birds are basically color blind compared to mantis shripms.

Shrimp color vision

Color spaces

A color space is a specific organization of colors. With color profiling of physical devices, it support reproducible colors: wall paint, print colors, or colors on a monitor or smart phone. It can use for example color names (like Pantone or RAL) or mathematical coordinates (CIELAB, sRGB, …).

Color models

A color model is an abstract mathematical model to represent colors - as typically 3 or 4 numbers/components. When the model is associated with a precise description how to interpret the components, then we can use it to represent a colors of a given color space.

Color model examples:

  • RYB - substractive, what you probably used in the elementary school with water paints
  • RGB - additive, what you most probably use during software development (!)
  • CMY/CMYK - substractive, color model for prints
  • HSL/HSV - cylindrical alternatives to RGB, more intuitive and user friendly

! The RGB color model is used for color spaces like sRGB, Adobe RGB or DCI-P3, but without defining the exact color space, the same RGB values might represent different colors on different devices (relative RGB color space)

sRGB and friends

Nothing “special”, since we are software developers :)

Gamut comparison

CIE 1931 XYZ and RGB

In the late 1920s the CIE RGB color space was defined based on actual human experiments, that basically covers all the colors that are visible to a person (even more) and from that the CIE XYZ color space was derived.

  • device-invariant

  • serves as a standard reference for many other color spaces

  • all coordinates are meaningful, but many (such as the [1, 0, 0], [0, 1, 0], [0, 0, 1] primary locations) are imaginary colors outside of the preceivable colors

  • well defined color matching functions

    • for example Y used for contrast ratio checks
    • various color diff functions
  • Y - the luminance (preceived by the observer)

  • Z - ~ the blue component of CIE RGB

  • X - a mix of the three CIE RGB curves


The CIELAB (or Lab*) color space was defined in 1976. It expresses colors as three values, based on the human color vison:

  • L - luminance, perceptual lightness (0 - 100)
  • a - red-green (unbounded, but -128 - 127)
  • b - blue-yellow (unbounded, but -128 - 127)

It was intended to be perceptually uniform which means that a given numerical change corresponds to a similar preceived change in color. Like doubling the value of a positive a will result in a color twice as green as the original.


CIELAB based cylindrical color space, which uses polar coordinates C (chroma, relative saturation) and h (hue angle in the color wheel). (L remains the same)

Similar to HSL/HSV color models, but LCh is still perceptually uniform like LAB. (!)

! Its uniformity is not perfect, blue hues are predicted badly, but newer color spaces address this issue, Oklab for example.

LAB blue issue

Why is this useful? It’s very hard to create perceptually smooth multi color gradients using the RGB color model, but it’s straightforward using LAB/LCH:

RGB vs LAB red-green-blue gradient


lab(), lch(), oklab() and oklch() are all covered in CSS Color Module Level 4 specification. Yes, it’s still in draft, but at the time of writing Safari, Chrome and Edge supports them already, and they are behind flag in Firefox too! 🎉