Colors
Length Units
Percentage Values
URLs
CSS2 Units
Summary
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.
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.
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.
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.
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.
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.
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.
Color |
Percentage Equivalent |
---|---|
red |
rgb(100%,0%,0%) |
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%);}
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.
Color |
Numeric RGB Equivalent |
---|---|
red |
rgb(255,0,0) |
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.
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.
Color |
Hexadecimal Equivalent |
---|---|
red |
#FF0000 |
#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.
Now, finally, the last method. Again, let's look at an example and then explain it:
H1 {color: #000;} /* set H1s to be black */ H2 {color: #666;} /* set H2s to be dark gray */ H3 {color: #FFF;} /* set H3s to be 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 we only have three digits total, how does this method work?
The answer is that the browser takes each digit and replicates it. Therefore, #F00 would be equivalent to #FF0000 -- and it's as simple as that. Otherwise, this method is the same as the #RRGGBB method we just discussed, only shorter. #6FA would be the same as #66FFAA, and #FFF would come out #FFFFFF, which is the same as white. This approach is sometimes called shorthand hex notation.
One thing to watch out for is that with the hexadecimal methods, unlike the numeric methods, there are no defined clipping methods for the hex-pair systems. If you enter an invalid value, the browser's response could be unpredictable. A well-written browser will perform clipping so that out-of-range values are assumed to be whichever limit they exceed, but you can't necessarily count on this. As an example, Netscape Navigator 4.x will not ignore or clip an invalid color value, but will instead perform some sort of magic translation to yield a totally unexpected color.
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.
Color |
Percentage |
Numeric |
Hex Pair |
Short Hex |
---|---|---|---|---|
red |
rgb(100%,0%,0%) |
rgb(255,0,0) |
#FF0000 |
#F00 |
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 |
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.
Copyright © 2002 O'Reilly & Associates. All rights reserved.