color chooser
about hslab

color chooser


rgb interval:       lightness mode:
no click

gradient generator

hi
hi

About hsLab

Graphic design for screens has a unique set of challenges when it comes to working with colors. There are a few key aspects of a good color design tool: it must have an intuitive color mixing paradigm, the lightness/darkness of a color must be accurately represented, and the results must exportable to the RGB color space. Current tools that work with just a single color space; for example, RGB, HSL, and LAB, fail to meet all three of these key aspects. The hsLab tool takes the good parts of working with these color spaces, and combines them into a better design experience.

This article is written from an exploratory point of view. I'll start with some basics, and explore why these failures exist, and from where these requirements arise.

  RGB
Format
Intuitive
Mixing
Accurate
Lightness
RGB
HSL
LAB

The Problems and Requirements

Starting and ending up with RGB

Screen design is inherently limited to display technology, and in all cases screens use a Red Green Blue color space to define what color a pixel will show. So, designers must, at least at some point in their process, realize their design colors in RGB. This will be our first requirement: that our tool must output colors in RGB.

Because RGB is required for defining colors for screen design, the laziest option is to work with and adjust colors in the RGB color space. There are two problems that arise while working in the RGB color space, though. One of which is obvious, the second of which is not.

The Intuitive Mixing problem

The first problem I'll outline is what I call the Intuitive Mixing problem. The inverse of this problem will become our second requirement: that our tool must allow for mixing and adjusting colors intuitively. This problem stems from the fact that, since screen design is actually light design, light color definitions are based on an additive color system.

Most of us have fond memories of painting when we were young. Teachers used this opportunity to have us learn about the primary colors: Red, Blue, and Yellow. With these three paint colors, you could mix them together to form any other color, like Blue + Yellow = Green. Then you got your hands messy, and actually got to create Green yourself... it was lots of fun!

Paint is an example of a subtractive color mixing system, because when white light hits a surface, some light is absorbed (or subtracted) and some light is reflected back. White light is a combination of all wavelengths of light, which is the same as saying it's the combination of all colors or hues of light. For example, red paint absorbs all color wavelengths of light except red, reflecting red light back. This is why if you mix all your color paint together, you'll get a dark brown or black - that's because it's absorbing most or all the different color wavelengths, and not allowing much to reflect back.

Painting when we were young is the last positive experience most of us had learning about color theory. A fair number of us also had to endure a brief section of physics and light in high school; but, on the whole, it probably wasn't as fun or inspiring as finger painting. This is actually the crux of the Intuitive Mixing problem, though. Mixing different color wavelengths of light together is actually an additive process. So mixing all them together equals white (not black), and Red + Green = Yellow.

The knee-jerk reaction to Red + Green = Yellow is why, in my opinion, the RGB color space fails the Intuitive Mixing requirement. Even for designers who work with RGB all the time, there seems to be something not quite right about it.

Here is an example of an RGB color that is mostly Red and Green:

So, we'll add it to the list. So far our comparison matrix looks like this:

  RGB
Format
Intuitive
Mixing
RGB

HSL to the rescue... kind of...

If you've ever fiddled with three RGB sliders, trying to get to a certain color, you'll quickly realize that it's not an efficient way to define a color. Shouldn't there be a way to take all the colors in the RGB color space, and arrange them in a more intuitive way? There is, in fact; and it's called HSL: Hue, Saturation, and Lightness.

HSL (and other systems, like HSV and HSB) eliminate the need to individually specify each additive primary color, and instead, has you specify three other metrics.

Hue is a more specific term to what might be referred to as a "base color". You can have dark green, light green, forest green, etc... but their base color is still just green.

Saturation is how pure that base color is. Saturation can be thought of as a gradient between the base color, and a gray color of equal lightness.

Lightness is probably the most intuitive aspect of HSL - it's really just how light or dark the color is. You can imagine a base color in the middle, with a gradient fading to white on one side, and fading to black on the other side.

Here is an example of an HSL color with a Blue hue, fairly saturated, and fairly dark:

As a side note, there are two cousins of HSL: HSV and HSB, which stand for Value and Brightness. They are similar concepts to Lightness, but not the same thing. For this discussion we'll be sticking to HSL.

Using HSL to define a color is conceptually much easier than using pure RGB values - which means HSL passes our Intuitive Mixing requirement. And even though we can't specify HSL values for screen design, they are easily translated to RGB values (once we've got the color we want). Actually, HSL and RGB share the same conceptual color space - another way of saying this is that HSL is just all the RGB colors re-arranged in a more logical way.

So, we've added another color space to our comparison matrix:

  RGB
Format
Intuitive
Mixing
RGB
HSL

If these were our only two requirements, working with HSL and translating to RGB would meet our needs for screen design. But wait, there is one more problem to overcome...

The Desaturation Problem

Designs usually require many colors, so designers are usually not just interested in one color, but how a set of colors look and interact in a single space. Hue is important because many base colors have social meanings (RED = BAD, GREEN = GOOD). But besides this, how colors contrast with each other is incredibly important. Does the color stand out and grab your attention? Or does it stand out just enough to be read? Contrast is a powerful tool in any design.

HSL lets us easily compare the lightness or darkness of any two colors. If you reduce the saturation component of a HSL color, you are left with a gray value, ranging from 0-100%. Finding this value for a set of colors makes it easy to mathematically compare the lightness, or difference of lightness (contrast) between all members of a set.

Let's say, for example, I want to work with a Blue and a Yellow of equal lightness. They are different hues, sure, but I don't want one to be darker or lighter than the other. So, I take a pure RGB Blue and Yellow, and desaturate them to find their relative lightness value. For dramatic effect, included below are the saturation steps 100%, 66%, 33%, and 0%.

The result of our desaturation process resulted in 50% lightness for each color. Which gives us our answer: the blue and yellow color above are just as light as each other.

This is where the problem comes in: those two colors are not the same lightness. We asked the RGB color space to do some math for us to see if one was lighter than the other, and the answer was "Equal lightness". But if we ask our eyeballs to determine which is darker, it's very clear the blue color is much darker than the yellow color. So what gives? It turns out the RGB color space is the wrong shape.

The RGB cube

The RGB color space is very simple to describe. The three additive primary colors can each be specified on a 256 point scale. All color spaces are three dimensional - one of the effects of this is that you can't lay out all the colors on a flat plane. The RGB color space happens to be a cube. It can be visualized by graphing each of the RGB components in three dimensions.

The corners of the RGB cube are the three additive primary colors (Red, Green, and Blue), the three additive secondary colors (Magenta, Yellow, and Cyan), plus Black and White. A single face of the RGB cube has a primary, two secondary, and a non-hue corner. The entire outside of the cube is comprised of fully saturated colors, and as we move toward the center of the cube, the colors become less saturated (or closer to 50% gray).

The reason the RGB color space is laid out like this is because it makes sense to computers. 256 happens to be a number that is stored well in computer memory, with no space wasted, so we're able to specify a large range of colors. Actually, there are 2563 distinct colors in the RGB color space, which equals 16,777,216. Each pixel on your screen is actually comprised of three sub-pixels: a Red, a Green, and a Blue. Each sub-pixel can be at lightness = 0 (all the way off), lightness = 255 (all the way on), or 254 steps in between. This is how more than 16 million screen colors are generated.

The computer doesn't differentiate between these colors. Incrementing the Red sub-pixel 10 levels is the same as incrementing the Green sub-pixel 10 levels. Spatially, that means all colors in the RGB cube are equidistant from each other. If we were to start at any color in the cube, and travel three colors to the left, or three colors to the right, the distance is the same. This may seem either confusing, or oversimplified, but it matters when we start talking about the gamut, or curve, of a color space.

This means we have a new requirement: Accurate Lightness.

  RGB
Format
Intuitive
Mixing
Accurate
Lightness
RGB
HSL

LAB to the rescue... kind of...

Remember the Yellow and Blue lightness problem outlined above. We asked RGB which one was lighter, and the answer was that they were the same lightness. That is because the Yellow corner and the Blue corner are equidistant from the center of the RGB cube.

The point is this: the RGB color space makes sense to computers, but it doesn't correspond to how the human eye perceives color. Taking our color space model, this means the human eye doesn't use a cube to sense how close or far away colors are from each other. For example, starting at a color, traveling three colors to the left and three colors to the right, you might be traveling different distances. So what is the shape of the color space that our eyes can see?

The LAB color space is a generic term that applies to many different efforts to answer this question. This color space was the result of decades of research that looked into how colors physically stimulated the eye. There are many LAB variants, each emphasizing different things. For our purposes, we're going to stick with CIE 1976 (L*, a*, b*) variant of the LAB color space, which is one of the more common ones.

So what is the shape of the LAB color space? Well, the specific answer is hard to describe. One of the limiting factors is that the human eye can see more colors than can be displayed through RGB... so if you're reading this on a computer, it's impossible to show a picture of the full LAB color space. But, for now, the important answer to the shape question is that it's curvy, and definitely not a cube. Darkness and Lightness are different, depending on what hue you are dealing with.

Many thanks to Jacob Rus and Wikipedia for this image.

Here is a look at three different slices of the LAB color space at 75%, 50%, and 25% lightness. Remember, the hard edges of these color shapes are not actually hard... but the point is that the color space our eyes see is kind of curvy, in all three dimensions.

The L in LAB stands for Lightness. With a little math, we can take a RGB color, and find out a more accurate lightness that isn't based on the RGB cube. For example, now we could graph the relative LAB lightness values of the RGB Spectrum. By RGB Spectrum I mean the Hue selection component in our HSL color chooser... or, RGB colors where saturation = 100% and lightness = 50%.

Looking at the graph it makes sense. There are some lightness peaks, around Yellow, Cyan, and Magenta, and there are some lightness valleys - mostly around blue, but around red, and green as well. We can use this new information to lay out colors in a way that accurately reflects that color's true lightness. LAB allows us access to accurate lightness... that is great news!

The bad news is that the other two dimensions of LAB are based on additive color mixing. The A dimension is colors between green and magenta, and the B dimension is colors between blue and yellow. This is a logical way organize a color space that applies to light. But, unfortunately, this means LAB fails our Intuitive Mixing requirement for the same reasons RGB fails.

But, we can add LAB to our comparison matrix to see how everything compares:

  RGB
Format
Intuitive
Mixing
Accurate
Lightness
RGB
HSL
LAB

Funny, I see a PASS in ever column...

The Solution: a new color space

Well, maybe not a new color space in the technical sense. But at least a tool that would satisfy all three requirements:

  RGB
Format
Intuitive
Mixing
Accurate
Lightness
RGB
HSL
LAB
hsLab

Formulas for converting between RGB, HSL, and LAB are widely available. So, essentially, this new tool will be a few points of color design philosophy, mixed with some color conversion math behind the scenes.

Some design criteria

Scope the tool to RGB color space

One of the first sections of this article was titled "Starting, and ending, with RGB". It might be tempting to base our new tool in the LAB color space: it can describe so many colors... including ones that fall outside of the RGB space, and even colors that can't be seen by humans. LAB was made to be comprehensive, and it is. But do we really need all that?

Since the goal of this tool is to help with screen design, we're actually going to take the confines of the RGB color space as a welcome restriction. The end goal is to determine a RGB color, so our starting set of possible colors should also be RGB.

16 million colors is too many

As we learned previously, the RGB color space can specify more than 16 million colors. The fact is, if you take two RGB colors that are one step different, and put them next to each other, it's impossible to tell them apart. Since RGB steps are 0-255, we can look at the factors of 255 to find step numbers that can traverse the RGB space without remainders. That is to say, if we start at zero, and step over a certain number of colors each time, we can land on 255 at the end.

Actually, walking through the RGB color space with the 51 step size will get you the old "Web Safe" color palette. But what the picture illustrates above is taking single steps will only result in imperceptible differences. Therefore, it will be a useful feature of our tool to chunk the entire RGB color space with larger step sizes.

Generating a color chooser

This is an overview of how our new tool will be laid out, and how colors in the chooser will be determined.

RGB Format for screen design

Since we're starting with the RGB color space, we can use a step to select an evenly distributed subset of the RGB color space. This will become our working set, and we can arrange these colors as we see fit.

Intuitive Mixing

This requirement will inform how our color chooser tool is laid out; or, how we're going to map our three dimensional color space onto a two dimensional tool. The one color space that met this requirement is HSL, so we'll borrow its format. The first choice, or control, will be the hue selector. Once a hue "base color" is selected (the first dimension) we'll lay out the other two dimensions in a square. The vertical axis of the square will be Lightness, and the horizontal axis will be Saturation.

Accurate Lightness

Even though our tool is laid out like a HSL tool, we will use LAB to compute the lightness component. The HSL definition of saturation and hue does not pose any problems, so we'll stick with those.

Bringing it all together

Here is a walkthrough of our process

  1. Choose a RGB step [5,15,17,51]
  2. Choose a HSL Hue that will be our base color
  3. Using the base color and the step size, create a subset of RGB colors that correspond to the two dimensional HSL saturation and lightness space
  4. For each color in this subset of colors, determine the LAB lightness
  5. Re-organize the two dimensional space with HSL saturation and LAB lightness

To use our Blue vs. Yellow example above, here's how the two colors are re-mapped with our new hsLab tool, with a RGB step of 5. The lightness value of the blue base color is 32%, while yellow's is 95% - a much better representation of their relative lightness.

Because these images use an aspect of LAB, they also show the curvy shape of the LAB color space.

A few final thoughts

The primary value of this tool is the accurate lightness comparison. In the tool, horizontal rows of colors have equal lightness. Laying out colors based on inherent properties should positively influence color choices.

The hsLab tool also begins to show interesting saturation patters. Columns of color have equal saturation - but when combined with the lightness dimension, they form these interesting "tree ring" like patterns. Most other color pickers artificially stretch these colors into a square. The hsLab tool lets the colors fall where they may, which better highlights their relationship to other colors in both the saturation and lightness dimension.

This is just one way to organize a set of colors... it emphasizes certain aspects and is scoped certain ways to meet specific needs. Is it the end-all-be-all color choosing tool? Well, probably not. But I like it, and if you don't like it, I encourage you to make your own.