Work in progress

Learn Colors

Color can be expressed in four different formats. There are a limited number of named colors, and then there are colors defined by specific values. For colors defined by specific values, CSS offers three different ways to express them:

Each format has advantages and disadvantages. For starters, let's see the same named color, royalblue, in all the formats:

/* Hexadecimal */
p {
  color: #4169e1;
/* Hue, Saturation, Lightness */
p {
  color: hsl(225, 73%, 57%);
/* Red, Green Blue */
p {
  color: rgb(65, 105, 225);

Each one of the rules above will make the paragraph elements on a page the same color blue. So if they're all the same, you're probably wondering, why does CSS offer so many ways of doing the same thing, defining color?

It all comes down to different use cases and who is defining color and consuming color.

What are those /* */ characters in the code above?

That's a code comment! Comments are lines ignored by the computer but used by programmers to leave notes (comments) to themselves or each other. In this case, I added a comment above each rule to tell you which color format we were using. In general, code is read more than it is written, so it's a good habit to comment your code.


Hexadecimal is the most common way you see colors defined, because a single numerical value can represent an entire color. When designing your own styles, you will most likely find yourself using a color picker like this one (click the input below):


The color picker tells you the values in each format (Hexadecimal, HSL, RGB) for the given color you've chosen.

Having a color represented as a single value is useful because it's easier for you to work with one value in your code and to go from color picker directly to CSS. You just copy the "Color name" hexadecimal value from the picker and then paste that single value into your CSS, and you're off to a colorful race track!

One shortcoming of defining colors in hexadecimal is that it's difficult for a human to read. The values are defined as #RRGGBB, meaning two places are saved for how much Red (RR), Green (GG), and Blue (BB) make up the whole color. However, it's hard to look at two colors, say #E71C1C, and #1C5AE7, and tell that they're a red and a blue.

Making color easier to understand for humans is where the Hue, Saturation, and Lightness color format come in.

Hue, Saturation, Lightness (HSL)

HSL was invented by a french engineer, Georges Valensi, who in 1938 was trying to solve a television broadcasting problem. TV broadcasters needed a way to maintain backwards compatability with monochrome (black and white) TV receivers and the new color TVs. Luminance (how much black or white existed) was broadcast as an unmodified value, so Mr. Valensi came up with the HSL color space in order to support color, while still maintaining compatibility with existing monochrome TVs.1


HSL color space is shaped as a cylinder, so the first attribute, hue, has an acceptable range aligned with the number of degrees in a circle (360). The hue (also called chroma) value chosen is essentially the base color. To see what I mean, I have created a table of color values below along with their hues, so you can see how each 30 degree "chunk" of the circle corresponds to actual colors. You can click on any of these color picker inputs to see how hue changes.

hot pink

So now, if you remember that Red is when Hue is 0, Green is when Hue is 120, and Blue is when Hue is 240, then for colors defined in the HSL format, you can pretty easily tell which ballpark you're in, just by looking at a single value (the first one, Hue). That's why HSL is often referred to as a human readable or human digestible color format.

It may be easier to see what I mean when we look at a color wheel with the Hue values annotated:

0 30 60 90 120 150 180 210 240 270 300 330

When defining color using HSL in CSS, you use the following format:

  color: hsl(hue, saturation, lightness);

Without knowing what saturation or lightness do, can you look at the CSS rule below and the hue value to guess the color?

p {
    color: hsl(230,75%,90%);
Guess the color before expanding this paragraph! Remember to use the color wheel for reference.

Did you guess a shade of blue? If so, well done! If not, look at hues and colors above once more. See how the hue for azure is 210 and the hue for blue is 240? Since the hue in the CSS rule above is 230, between azure and blue, we could safely guess that the paragraph would be colored some shade of blue.

Next we're going to learn how the rest of the HSL color format is defined.


Saturation is a value that ranges from 0-100% and it defines how much or how strong the color you've chosen appears. In our example below, we'll use purple to see how changing the saturation changes the color. A total lack of saturation (no color) leaves us with just white, while full saturation (all the color) results in a bold purple.

Saturation 0 10 20 30 40 50 60 70 80 90 100


Lightness is a value that also ranges from 0-100%, but it defines how much black (0%) or white (100%) is in the color. As you can imagine, a total lack of lightness (0%) results in a black color, while full lightness (100%) gives you bright, fully lit colors.

Lightness 0 10 20 30 40 50 60 70 80 90 100

Stepping back for a second to combine our new understanding for all three aspects of the HSL format:

It's now easier for us to return to our original guessing example and see how the different values effect the color rendered:

p {
    color: hsl(230,75%,90%);

We definitely have a blue (hue = 230), there's a lot of blue (saturation = 75%), and it's a bright shade of blue (lightness = 90%).

If HSL is easier for humans, then what about computers? How do they make sense of color?

That's why we have RGB.

Red, Green, Blue (RGB)

The red, green, blue or RGB color model is based on adding three base colors together (you've probably already guessed which) to produce every other color in the rainbow. Unlike HSL where hue is essentially the color, RGB colors are determined by how much of each base color is present. RGB values can range from 0-255 with 0 representing none of the color being present and 255 representing the maximum of that color. The color notation is similar to that of HSL, except with rgb instead:

  color: rgb(red,green,blue);
Values rgb(255,0,0) rgb(0,255,0) rgb(0,0,255)

So, if you want a color like orange, then what colors combined make orange? Can you guess?

Click here to see the answer!

To make orange you start with a lot of red (255) and then add about half green (125). You don't need any blue (0).

  color: rgb(255,125,0)

And you get a bright, strong, bold orange like this:

That was probably pretty difficult to guess though, right?

Imagine if you saw a color defined like this:

p {
    color: rgb(65, 105, 225);

Any idea what color that might be?

There's about 25% of the possible red, 40% of the possible green, and a large amount of blue 90%ish. It's probably a blue, and maybe it's some sort of green-ish blue, since there's so much green in it?

I can't really tell what color this will end up as just based off the raw RGB values.

Guess what? It's our original royalblue.

That's why RGB is a color format designed for computers and electronic devices. It's not very human readable.

So why does RGB exist?

Well, the combination of 256 values (0 to 255) of each color means that 16,777,216 (256 * 256 * 256) precisely defined colors are available in this color format. That's a huge color spectrum. Also, defining color in this way is easier, computationally, on computers. Today, that doesn't matter anymore, because computers are very fast, but when different color formats were being adopted by early computers, this mattered a lot.

Alpha Channel

Finally, for both RGB and HSL color definitions, you have the option of adding an additional dimension for transparency. This is called the alpha channel, and it defines how transparent the color renders. The values for Alpha range from 0-1 with 0 representing full transparency (invisible) and 1 representing full color (no transparency). This royalblue definition using rgba is the same as not specifying alpha:

p {
    color: rgba(65, 105, 225, 1)

The alpha channel is typically used for backgrounds, because it allows you to blend different colors together on multiple layers.

p {
    background-color: hsla(30, 75%, 57%, 0.25);
    color: hsla(225, 73%, 57%, 0.75);

Blending color with alpha opens another door to displaying elements together using CSS!

The paragraph above actually has a bright, bold orange color selected for its background, but it's rendering as a faded orange because the alpha channel is telling the browser to only render it at 25% transparency. The same is true for the faded blue of the text, which is our same royalblue, but is now set at 75% transparency and is blending in with the background orange.


Using color correctly means making it accessible to everyone, even those with visual impairments. This is part of embracing the idea of universal design. Universal design in physical buildings is the idea that all people should have equal access to a building, regardless of their level of mobility. That's why buildings have ramps for people in wheelchairs. The same is true for our digital world on the web. Every user, regardless of their situation, should have the same ease of access to your website. This includes users that are visually impaired and might have difficulty discerning between similar colors.

There's a lot to learn about getting color contrast right, and I want you to read from the experts:

In the future, this section will be expanded to cover accessibility further, but for now, please rely on the above.

You've learned a lot about color. Now what about fonts and typography?


1Read more about Mr. Valensi and HSL on Wikipedia.

Back Next: Typography