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. 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. 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.4. Short hexadecimal colors
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.
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.
 |  |  | | 2.10. Summary |  | 3.2. Length Units |
Copyright © 2002 O'Reilly & Associates. All rights reserved.
|