home | O'Reilly's CD bookshelfs | FreeBSD | Linux | Cisco | Cisco Exam  


Book HomeCascading Style Sheets: The Definitive GuideSearch this book

Chapter 3. Units and Values

In this chapter, we study the basis for almost everything that can be done in CSS: the units that affect the color used or the distance set for a whole host of properties. Without units, it wouldn't be possible to declare that a paragraph should be purple, or that an image should have ten pixels of blank space around it, or that a heading should be a certain size. By understanding the concepts put forth here, you'll be able to learn and use the rest of CSS much more quickly.

However, that's the good news. The bad news is that this chapter will contain a good many caveats, warnings, and discussions of browser bugs and inconsistencies between operating systems. Remember, though, that CSS is not supposed to be a totally precise layout language -- and besides, many of the issues discussed in the chapter are not the fault of CSS but are more fundamental issues that you'll encounter no matter what you try to do with a computer. So, once you've finished this chapter, you will have a grasp not only of how CSS units work, but perhaps also of a few basic issues that you previously were unaware of.

Above all, though, regardless of how bleak things may seem, keep going! Your perseverance will be rewarded.

3.1. Colors

Of course, the one thing that almost every beginning web author wants to know is, "How do I set colors on my web page?" Under HTML, there were two choices: use one of a small number of colors with names, like red or purple, or employ a vaguely cryptic method using hexadecimal codes. Well, both of those methods for describing colors can be found in CSS, as well as some other methods that are only moderately complex.

3.1.1. Named Colors

Assuming that you're happy with picking from a small, basic set of colors, then the easiest method is to simply use the name of the color you want. These are referred to, unsurprisingly enough, as named colors.

Contrary to what some browser companies might have you believe, you are limited in the range of named colors available. For example, setting a color to "mother-of-pearl" isn't going to work, because it isn't a defined color. (Well, not yet, at any rate.) Technically speaking, there are no defined colors, but there are 16 colors that are suggested by the specification and that all major browsers recognize:

aqua

gray

navy

silver

black

green

olive

teal

blue

lime

purple

white

fuchsia

maroon

red

yellow

If these seem like odd color names, it's because -- well, they are. In my opinion, anyway. So where do they come from? These colors were taken from the original sixteen basic Windows VGA colors, and browsers are supposed to generate colors that at least come close to matching those original 16. They may be a fairly motley collection of colors, but they're what we have.

So let's say we want all first-level headings to be maroon. The best declaration would be:

H1 {color: maroon;}

Simple, straightforward, and difficult to forget. It doesn't get much better than that. Here are a few more examples:

H1 {color: gray;}
H2 {color: silver;}
H3 {color: black;}

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

H1 {color: orange;}

you're likely to see all of your H1 elements colored orange, despite the fact orange isn't on the list of named colors. This is due to the fact that most web browsers recognize as many as 140 color names, including the standard sixteen. There are two problems associated with using these extra names, though. The first is that not all browsers will recognize them; Opera, for example, sticks with the standard 16 colors, at least in the Opera 3.x series. Far from being a failure on their part, this represents a remarkable commitment to standards support, even though it might confuse or annoy many web designers.

The second problem is a little more fundamental: there are no standard color values for these names. Declaring that an element should be colored orange doesn't mean that different browsers, or even the same browser running on different platforms, will produce exactly the same shade of orange. With the sixteen standard colors, there is at least some hope that they will appear as similar as possible, because the color values for these sixteen are defined. Beyond those, all bets are off. Browsers may implement similar shades for the same color name, or they may not; the differences may be imperceptible to the eye, or so obvious that they're almost jarring.

Reproducing Colors

Consistent color reproduction is, as it happens, a major issue unto itself. As we'll soon see, all colors can be specified in a consistent manner, which would seem to solve the issue of whether two different user agents will display the same color. In fact, the situation is much more complicated. In the first place, human perception is relative. The same color displayed on the same monitor may appear to change due to changes in lighting, ambient brightness, adjacent colors, and many other factors. You can experiment with this effect simply by changing the background color of your computer's desktop. The colors of your icons will appear to subtly shift as you do so.

In an attempt to address this situation, displays such as monitors usually have a default gamma value set; this is a factor that modifies colors to account for display conditions. The gamma is typically set via the operating system, although more expensive monitors may have their own gamma settings. The problem is that different systems have different gamma values. Thus, if you were to create a web page with a color background and then display it on Windows and Macintosh machines side by side under identical lighting conditions, the background color would look different on each machine. This also crops up in graphics created for the Web, in that graphics created on Windows machines tend to appear darker to Macintosh users, whereas images created on a Macintosh look lighter for Windows users.

The situation degrades even further when colors are printed, since factors as diverse as the stock and color of the paper used, and even the temperature of the printing mechanism, can affect how well colors are reproduced on paper.

In effect, this is yet another area where you must remember that total control over document appearance is simply not possible. In this case, it's due to a combination of inconsistent operating system settings and the vagaries of human perception, which is an obstacle no computer is going to overcome any time soon.

It is left to individual authors to decide what chances they wish to take with using named colors, but at least with the specified sixteen colors, there is some moderate hope of consistency.

Okay, so that was the easiest way to specify color -- scary as that may seem, it's true. The other four ways are a bit more complicated. The advantage is that with these methods, you can specify any color in the 8-bit color spectrum, not just sixteen (or however many) named colors. This is accomplished by taking advantage of the way colors are generated by computers.

3.1.2. 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 that there are three "guns." (Remember, however, that actually looking for these guns will pretty much void your monitor's warranty.) These guns shoot out beams of light in varying levels of light and dark, in one of the three RGB colors, at each point on the screen. The brightnesses of each of these beams combine at each point to form all of the colors you see on your screen. Each point, by the way, is known as a pixel, which is a term to which we'll return later in the chapter.

Given the way colors are created on a monitor, it makes sense that a good way to let you set colors is to give you direct access to those color levels, thereby determining your own mixture of the beams. This method is a bit more complex, obviously, but the payoffs are worth it because you aren't limited to whichever colors have been named.

3.1.2.1. Percentage colors

There are, in fact, four ways to affect RGB color. The first way we'll examine is perhaps the easiest to grasp because it uses percentages. Here's an example:

rgb(100%,100%,100%)

This color declaration sets the level of red to its maximum, blue to maximum, and green the same. These combine to create white, which is, after all, the combination of all colors. Alternatively, in order to specify black -- the absence of color -- all three would be set to 0%. Here are a few more color declarations:

H1 {color: rgb(0%,0%,0%);}          /*black*/
H2 {color: rgb(50%,50%,50%);}       /*medium gray*/
H3 {color: rgb(25%,66%,40%);}

The general syntax of this type of color value is:

rgb(color)

where color is one of two ways to specify the color. The first way is to use percentages, and the second, which uses numbers, is discussed later in this section.

Perhaps you want your H1 elements to be colored a shade of red somewhere between the values for red and maroon. red is simply rgb(100%,0%,0%), whereas maroon is more like (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 that of maroon, but darker than that of red. If, on the other hand, you wished to create a pale red color, then you would want to raise the other two values:

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

The easiest way to visualize how these percentages 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 have to do:

P.one {color: rgb(0%,0%,0%);}
P.two {color: rgb(20%,20%,20%);}
P.three {color: rgb(60%,60%,60%);}
P.four {color: rgb(80%,80%,80%);}
P.five {color: rgb(100%,100%,100%);}

Figure 3-1 shows what the various percentage values will yield.

Figure 3-1

Figure 3-1. Grayscale values

Of course, since we're dealing in shades of gray, all three RGB numbers are the same in each statement. If any one of them was 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 gray with just a hint of blue.

The equivalents for the various rainbow primaries, plus a few others, are presented in Table 3-1.

Table 3-1. Numeric RGB Equivalents for Common Colors

Color

Percentage Equivalent

red

rgb(100%,0%,0%)

orange

rgb(100%,40%,0%)

yellow

rgb(100%,100%,0%)

green

rgb(0%,100%,0%)

blue

rgb(0%,0%,100%)

indigo

rgb(20%,0%,100%)

violet

rgb(80%,0%,100%)

medium gray

rgb(50%,50%,50%)

dark gray

rgb(20%,20%,20%)

tan

rgb(100%,80%,60%)

gold

rgb(100%,80%,0%)

purple

rgb(100%,0%,100%)

It is also possible, at least in theory, to use fractional values. For example, you might want a color to be exactly 25.5% red, 40% green, and 98.6% blue. Not a problem:

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

Actually, there is a problem. Some user agents may not recognize decimal values, and still others could interpret them as if the decimal wasn't there, which would lead them to think the preceding value is actually rgb(255%,40%,986%). In that case, assuming the user agent behaves correctly, the out-of-range values will be "clipped" to the nearest legal value -- in this case, 100%. Thus, a user agent which ignores the decimal points should act as if the declared value is rgb(100%,40%,100%). Whether it does so is, of course, another story altogether. Also, negative values aren't allowed, so any value set to be less than 0% should be clipped to that amount. For example, the following values would be clipped as demonstrated in Figure 3-2:

P.one {color: rgb(300%,4200%,110%);}
P.two {color: rgb(0%,-40%,-5000%);}
Figure 3-2

Figure 3-2. Out-of-range values are clipped

3.1.2.2. Going by numbers

Closely related to percentages is a method of setting color using raw numbers. These numbers are on a scale from to 255, where rgb(0,0,0) represents black and rgb(255,255,255) represents white. Most of you will recognize this number range from other sources: it's the decimal equivalent of an 8-bit binary number. If you don't recognize this, then it's enough to know that computers employ binary values (on/off ) for everything, including representations of numbers and colors, and 255 is one of the numbers that just naturally fall out of that sort of setup.

Anyway, this is almost exactly the same as setting percentage values: only the scale is different, going up to 255 instead of 100%. Accordingly, the values in Table 3-2 correspond to our usual list of colors.

Table 3-2. Numeric RGB Equivalents for Common Colors

Color

Numeric RGB Equivalent

red

rgb(255,0,0)

orange

rgb(255,102,0)

yellow

rgb(255,255,0)

green

rgb(0,255,0)

blue

rgb(0,0,255)

indigo

rgb(51,0,255)

violet

rgb(204,0,255)

medium gray

rgb(128,128,128)

dark gray

rgb(51,51,51)

tan

rgb(255,204,153)

gold

rgb(255,204,0)

purple

rgb(255,0,255)

As expected, any value outside the range of -255 is clipped, just as with percentages -- although in this case, of course, the values are clipped to 0 and 255:

H1 {color: rgb(0,0,0);}                /* black */
H2 {color: rgb(127,127,127);}          /* gray */
H3 {color: rgb(255,255,255);}          /* white */
P.one {color: rgb(300,2500,101);}      /* white */
P.two {color: rgb(-10,-450,-2);}       /* black */

If you prefer percentages, you can use them, and it's actually easy to convert between percentages and straight numbers. 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. Multiplying each of those percentages by 255, we get 63.75, 95.625, and 153. We need to round those off to rgb(64,96,153), however, because only integers (whole numbers) are permitted when using numbers. Percentages can have decimals, but these numbers can't.

Of course, if you already know the percentages, there isn't much point in converting them into straight numbers. This notation is more useful for people who use programs such as Photoshop, which produce such color values, or for those who are familiar enough with the technical details of color generation to already think in terms of 0-255 values.

Then again, such people are probably more familiar with thinking in hexadecimal notation, which is what we turn to next.

3.1.2.3. Hexadecimal colors

If you've done any web authoring in the past and have ever set a color in the course of that authoring, then this part will be a snap. You can set a color using the same hexadecimal notation so familiar to web authors:

H1 {color: #FF0000;}   /* set H1's to red */
H2 {color: #903BC0;}   /* set H2's to a dusky purple */
H3 {color: #000000;}   /* set H3's to be black */
H4 {color: #808080;}   /* set H4's to be medium gray */

If you aren't familiar with this notation, here's a quick primer. First, hexadecimal means base-16 counting, so the basic unit is groups of 16, not the groups of 10 to which we're accustomed. In hexadecimal numbering, the valid digits are 0 through 9 and A through F. Once you've reached F, the next number is 10. Thus, a child learning to count in hex would learn this basic progression:

00, 01, 02, 03, 04, 05, 06, 07, 08, 09, 0A, 0B, 0C, 0D, 0E, 0F,
10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 1A, 1B, 1C, 1D, 1E, 1F,
20, 21, 22, 23, ...

I realize that it may be a bit weird to think of letters as numbers, but that's how it works in hex. The digits A through F are actually just symbols -- they could have been anything. Someone just decided that letters would be easier to remember than invented symbols... plus nobody would have to invent new names for letters.

How this corresponds to our regular decimal (base 10) numbering is fairly straightforward. 05 is equal to 5, 0C is equal to 12, 0F is the same as 15, and 10 is equal to 16. No, really. 1F is equal to 31, 20 to 32, and so on. It goes like this:

01, 02, 03, 04, 05, 06, 07, 08, 09, 0A, 0B, 0C, 0D, 0E, 0F,
01, 02, 03, 04, 05, 06 ,07, 08, 09, 10, 11, 12, 13, 14, 15, 16,

10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 1A, 1B, 1C, 1D, 1E, 1F,
17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,

20, 21, 22, 23, ...
33, 34, 35, 36, ...

Computers have been using hex notation for quite some time now, and typically programmers either are trained in its use or pick it up through experience. Either way, most programmers are comfortable with hex notation -- some of them even think in it -- and so it's part of the CSS specification. Why? Because the specification was written and edited by programmers. It makes sense that they'd put in color schemes to which they could relate.

So, by stringing together three hex pairs, you can set a color. A more generic description of this method is:

#RRGGBB

Viewed in this way, the hex-pair method is a lot like the method we previously discussed -- the one involving numbers from to 255. In fact, 255 in decimal is equivalent to FF in hexadecimal, which explains a lot about how this method works. It's really the same as the last method: it just uses a different number system. If you have to pick between the two, use whichever makes you more comfortable.

So, similar to the way you can specify a color using three numbers from to 255, you can specify one using three hex pairs. If you have a calculator that converts between decimal and hexadecimal, then making the jump should be pretty simple. If not, it might be a little more complicated. (Of course, you could just not use this method, but that would be too easy.)

Once again, we present some color equivalents in Table 3-3.

Table 3-3. Hexadecimal Equivalents for Common Colors

Color

Hexadecimal Equivalent

red

#FF0000

orange

#FF6600

yellow

#FFFF00

green

#00FF00

blue

#0000FF

indigo

#3300FF

violet

#CC00FF

medium gray

#808080

dark gray

#333333

tan

#FFCC99

gold

#FFCC00

purple

#FF00FF

Believe it or not, though, there's a way to set colors that involves even fewer keystrokes.

3.1.2.5. Bringing the colors together

Table 3-4 presents an overview of the colors we've discussed. Italicized color names are those that can be legally used as values of a color declaration. Those without italics might not be recognized by browsers and therefore should be defined with either RGB or hexadecimal 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 3-4. Color Equivalents

Color

Percentage

Numeric

Hex Pair

Short Hex

red

rgb(100%,0%,0%)

rgb(255,0,0)

#FF0000

#F00

orange

rgb(100%,40%,0%)

rgb(255,102,0)

#FF6600

#F60

yellow

rgb(100%,100%,0%)

rgb(255,255,0)

#FFFF00

#FF0

green

rgb(0%,100%,0%)

rgb(0,255,0)

#00FF00

#0F0

blue

rgb(0%,0%,100%)

rgb(0,0,255)

#0000FF

#00F

indigo

rgb(20%,0%,100%)

rgb(51,0,255)

#3300FF

#30F

violet

rgb(80%,0%,100%)

rgb(204,0,255)

#CC00FF

#C0F

aqua

rgb(0%,100%,100%)

rgb(0,255,255)

#00FFFF

#0FF

black

rgb(0%,0%,0%)

rgb(0,0,0)

#000000

#000

fuschia

rgb(100%,0%,100%)

rgb(255,0,255)

#FF00FF

#F0F

gray

rgb(50%,50%,50%)

rgb(128,128,128)

#808080

lime

rgb(0%,100%,0%)

rgb(0,255,0)

#00FF00

#0F0

maroon

rgb(50%,0%,0%)

rgb(128,0,0)

#800000

navy

rgb(0%,0%,50%)

rgb(0,0,128)

#000080

olive

rgb(50%,50%,0%)

rgb(128,128,0)

#808000

purple

rgb(50%,0%,50%)

rgb(128,0,128)

#800080

silver

rgb(75%,75%,75%)

rgb(192,192,192)

#C0C0C0

teal

rgb(0%,50%,50%)

rgb(0,128,128)

#008080

white

rgb(100%,100%,100%)

rgb(255,255,255)

#FFFFFF

#FFF

dark gray

rgb(20%,20%,20%)

rgb(51,51,51)

#333333

#333

tan

rgb(100%,80%,60%)

rgb(255,204,153)

#FFCC99

#FC9

3.1.2.6. Web-safe colors

You may recall the earlier discussion about how colors aren't always the same across different operating systems, user agents, and so forth. There is one way to partially beat this problem, although once again it means restricting your color choices. There is a set of 216 colors that are considered "web-safe," which means they should look the same on all computers and browsers, without any dithering or color-shifting. Note that I say "should" -- this is not a guarantee. It generally seems to work, however.

Web-safe colors are those colors that are 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, then 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, then values should be either 0 or divisible by 51, as in rgb(0,204,153) or rgb(255,0,102).

With hex pairs, the appropriate values are 00, 33, 66, 99, CC, and FF. Any hex-pair triplet using those values in any combination 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.

Wow! Who knew there were so many ways to define a color? I'll bet you'll never look at a rainbow in quite the same way again. Now, let's move on to units that really measure up.



Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.