One of the first questions every starting web author asks is, “How do I set colors on my page?” Under HTML, you had two choices: you could use one of a small number of colors with names, like red or purple, or employ a vaguely cryptic method using hexadecimal codes. Both of these methods for describing colors remain in CSS, along with some other—and, I think, more intuitive—methods.

Named Colors

Assuming that you’re content to pick from a small, basic set of colors, the easiest method is simply to use the name of the color you want. CSS calls these color choices, logically enough, named colors.

Contrary to what some browser makers might have you believe, you have a limited palette of named-color keywords. For example, you’re not going to be able to choose “mother-of-pearl” because it isn’t a defined color. As of CSS2.1, the CSS specification defines 17 color names. These are the 16 colors defined in HTML 4.01 plus orange:


















So, let’s say you want all first-level headings to be maroon. The best declaration would be:

h1 {color: maroon;}

Simple and straightforward, isn’t it? Figure 4-1 shows a few more examples:

h1 {color: gray;}
h2 {color: silver;}
h3 {color: black;}
Naming colors

Figure 4-1. Naming colors

Of course, you’ve probably seen (and maybe even used) color names besides the ones listed earlier. For example, if you specify:

h1 {color: lightgreen;}

it’s likely that all of your h1 elements will indeed turn light green, despite lightgreen not being on the list of named colors in CSS2.1. It works because most web browsers recognize as many as 140 color names, including the standard 17. These extra colors are defined in the CSS3 Color specification, which is not covered in this book. The 17 standard colors (as of this writing) are likely to be more reliable than the longer list of 140 or so colors because the color values for these 17 are defined by CSS2.1. The extended list of 140 colors given in CSS3 is based on the standard X11 RGB values that have been in use for decades, and so they are likely to be very well supported.

Fortunately, there are more detailed and precise ways to specify colors in CSS. The advantage is that, with these methods, you can specify any color in the 8-bit color spectrum, not just 17 (or 140) named colors.

Colors by RGB

Computers create colors by combining different levels of red, green, and blue, which is why color in computers is often referred to as RGB color. In fact, if you were to open up a computer monitor, or even a television, and you got far enough into the projection tube, you would discover three “guns.” (I don’t recommend trying to find the guns, though, if you’re worried about voiding your monitor’s warranty.) These guns shoot out beams of light at varying levels of light and dark, in one of the three RGB colors, at each point on the screen. Then, the brightness of each beam combines at those points on your screen, forming all of the colors you see. Each point, by the way, is known as a pixel, which is a term we’ll return to later in this chapter.

Given the way colors are created on a monitor, it makes sense that for maximum control, you should have direct access to those color guns, determining your own mixture of the beams. That solution is complex, but possible, and the payoffs are worth it because there are very few limits on which colors you can produce. There are four ways to affect color in this way.

Functional RGB colors

There are two color value types that use functional RGB notation as opposed to hexadecimal notation. The generic syntax for this type of color value is rgb(color), where color is expressed using a triplet of either percentages or integers. The percentage values can be in the range 0%-100%, and the integers can be in the range 0-255.

Thus, to specify white and black respectively using percentage notation, the values would be:


Using the integer-triplet notation, the same colors would be represented as:


Assume you want your h1 elements to be colored a shade of red somewhere between the values for red and maroon. red is equivalent to rgb(100%,0%,0%), whereas maroon is equal to (50%,0%,0%). In order to get a color between those two, you might try this:

h1 {color: rgb(75%,0%,0%);}

This makes the red component of the color lighter than maroon, but darker than red. If, on the other hand, you want to create a pale red color, you would raise the green and blue levels:

h1 {color: rgb(75%,50%,50%);}

The closest equivalent color using integer-triplet notation is:

h1 {color: rgb(191,127,127);}

The easiest way to visualize how these values correspond to color is to create a table of gray values. Besides, grayscale printing is all we can afford for this book, so that’s what we’ll do in Figure 4-2: {color: rgb(0%,0%,0%);}
p.two {color: rgb(20%,20%,20%);}
p.three {color: rgb(40%,40%,40%);}
p.four {color: rgb(60%,60%,60%);}
p.five {color: rgb(80%,80%,80%);}
p.six {color: rgb(0,0,0);} {color: rgb(51,51,51);}
p.eight {color: rgb(102,102,102);}
p.nine {color: rgb(153,153,153);}
p.ten {color: rgb(204,204,204);}
Text set in shades of gray

Figure 4-2. Text set in shades of gray

Of course, since we’re dealing in shades of gray, all three RGB values are the same in each statement. If any one of them were different from the others, then a color would start to emerge. If, for example, rgb(50%,50%,50%) were modified to be rgb(50%,50%,60%), the result would be a medium-dark color with just a hint of blue.

It is possible to use fractional numbers in percentage notation. You might, for some reason, want to specify that a color be exactly 25.5% red, 40% green, and 98.6% blue:

h2 {color: rgb(25.5%,40%,98.6%);}

A user agent that ignores the decimal points (and some do) should round the value to the nearest integer, resulting in a declared value of rgb(26%,40%,99%). In integer triplets, of course, you are limited to integers.

Values that fall outside the allowed range for each notation are “clipped” to the nearest range edge, meaning that a value that exceeds 100% or is less than 0% will default to those allowed extremes. Thus, the following declarations would be treated as if they were the values indicated in the comments: {color: rgb(300%,4200%,110%);}   /*  100%,100%,100%  */
P.two {color: rgb(0%,-40%,-5000%);}   /*  0%,0%,0%  */
p.three {color: rgb(42,444,-13);}    /* 42,255,0  */

Conversion between percentages and integers may seem arbitrary, but there’s no need to guess at the integer you want—there’s a simple formula for calculating them. If you know the percentages for each of the RGB levels you want, then you need only apply them to the number 255 to get the resulting values. Let’s say you have a color of 25% red, 37.5% green, and 60% blue. Multiply each of these percentages by 255, and you get 63.75, 95.625, and 153. Round these values to the nearest integers, and voilà: rgb(64,96,153).

Of course, if you already know the percentage values, there isn’t much point in converting them into integers. Integer notation is more useful for people who use programs such as Photoshop, which can display integer values in the “Info” dialog, or for those who are so familiar with the technical details of color generation that they normally think in values of 0-255. Then again, such people are probably more familiar with thinking in hexadecimal notation, which is our next topic.

Hexadecimal RGB colors

CSS allows you to define a color using the same hexadecimal color notation so familiar to HTML web authors:

h1 {color: #FF0000;}   /* set H1s to red */
h2 {color: #903BC0;}   /* set H2s to a dusky purple */
h3 {color: #000000;}   /* set H3s to black */
h4 {color: #808080;}   /* set H4s to medium gray */

Computers have been using hex notation for quite some time now, and programmers are typically either trained in its use or pick it up through experience. This hexadecimal familiarity among programmers likely led to its use in setting colors in old-school HTML. The practice was simply carried over to CSS.

Here’s how it works: by stringing together three hexadecimal numbers in the range 00 through FF, you can set a color. The generic syntax for this notation is #RRGGBB. Note that there are no spaces, commas, or other separators between the three numbers.

Hexadecimal notation is mathematically equivalent to the integer-pair notation discussed in the previous section. For example, rgb(255,255,255) is precisely equivalent to #FFFFFF, and rgb(51,102,128) is the same as #336680. Feel free to use whichever notation you prefer—they’ll be rendered identically by most user agents. If you have a calculator that converts between decimal and hexadecimal, making the jump from one to the other should be pretty simple.

For hexadecimal numbers that are composed of three matched pairs of digits, CSS permits a shortened notation. The generic syntax of this notation is #RGB:

h1 {color: #000;}   /* set H1s to black */
h2 {color: #666;}   /* set H2s to dark gray */
h3 {color: #FFF;}   /* set H3s to white */

As you can see from the markup, there are only three digits in each color value. However, since hexadecimal numbers between 00 and FF need two digits each, and you have only three total digits, how does this method work?

The answer is that the browser takes each digit and replicates it. Therefore, #F00 is equivalent to #FF0000, #6FA would be the same as #66FFAA, and #FFF would come out #FFFFFF, which is the same as white. Obviously, not every color can be represented in this manner. Medium gray, for example, would be written in standard hexadecimal notation as #808080. This cannot be expressed in shorthand; the closest equivalent would be #888, which is the same as #888888.

Bringing the colors together

Table 4-1 presents an overview of some of the colors we’ve discussed. These color keywords might not be recognized by browsers and, therefore, they should be defined with either RGB or hex-pair values (just to be safe). In addition, there are some shortened hexadecimal values that do not appear at all. In these cases, the longer (6-digit) values cannot be shortened because they do not replicate. For example, the value #880 expands to #888800, not #808000 (otherwise known as olive). Therefore, there is no shortened version of #808000, and the appropriate entry in the table is left blank.

Table 4-1. Color equivalents





Short hex



Web-safe colors

The “web-safe” colors are those colors that generally avoid dithering on 256-color computer systems. Web-safe colors can be expressed in multiples of the RGB values 20% and 51, and the corresponding hex-pair value 33. Also, 0% or 0 is a safe value. So, if you use RGB percentages, make all three values either 0% or a number divisible by 20—for example, rgb(40%,100%,80%) or rgb(60%,0%,0%). If you use RGB values on the 0-255 scale, the values should be either 0 or divisible by 51, as in rgb(0,204,153) or rgb(255,0,102).

With hexadecimal notation, any triplet using the values 00, 33, 66, 99, CC, and FF is considered to be web-safe. Examples are #669933, #00CC66, and #FF00FF. This means the shorthand hex values that are web-safe are 0, 3, 6, 9, C, and F; therefore, #693, #0C6, and #F0F are examples of web-safe colors.

Get Cascading Style Sheets: The Definitive Guide, Second Edition now with the O’Reilly learning platform.

O’Reilly members experience live online training, plus books, videos, and digital content from nearly 200 publishers.