Font Size Does Matter
Web Review
August 1999
In the pursuit of the perfect page design through CSS, most authors will try exerting influence over the page's font. The first thing is usually to set the type of font, using properties like font-family
(for more on this subject, see the Sense of Style article "All In The Font Family"). The next thing authors usually try to do is affect the size of the fonts-- and that's where the trouble really starts.
CSS offers a variety of methods to affect the size of text, all of them involving the property font-size
. As it turns out, though, every single one of them is fraught with some kind of danger or drawback. This month, we'll examine two methods of changing the font size, and the pitfalls one might encounter. With this knowledge, you'll be able to decide which works best for you in any given situation.
Absolute Sizes
The easiest method to use involves the use of keywords, each of which corresponds to a certain absolute size. These seven keywords are:
medium xx-small xx-large x-small x-large small large
...and the default value is medium
. Remember that default value, because it'll become very important to a later disscussion.
Using these keywords is quite easy. Let's say you want all H1
elements to be extra large. This is done as follows:
H1 {font-size: x-large;}
On the other hand, you might want to make the text in a footer small. Here's one way to do that:
DIV.footer {font-size: small;}
The relationship between these sizes is not precisely defined in CSS, but there is a suggested scaling factor of about 1.2, which means that if medium
is equivalent to 12pt
, then small
will be about 10pt
, x-small
will be roughly 8pt
, large
will be approximately 14pt, and so on. Current browsers do seem to have used this scaling factor, so there isn't a major difference in font sizing on this account.
The thing about these sizes is that they will never change, no matter what the user does (short of turning off stylesheets, of course). Once the absolute-size keywords are used on an element, that element's font size is locked into place. If the user tries to resize the text through his browser, any element with an absolute font size will not change, although any other element will. This prevents users from making your page's text larger if they need to see it more clearly, or smaller if they think it's too big.
This probably all seems very simple. Nothing could possibly be difficult about this, right?
Inconsistent, But Not In Error
Sadly, not so. The problem with absolute-size keywords is that they don't match up between Explorer and Navigator, and they might not match up between any browsers at all.
The reason for this is as simple as it is frustrating. The CSS specification says that each of these sizes is assigned to a certain font size, and that these values never change. Therefore, if a browser assigns medium
to be 12 points, then any font whose size is set to medium
will be 12 points in size. The problem is that the specification doesn't say what size each keyword should equate. Browser A could set medium
to be the same as 11pt
, while Browser B sets it to 13pt
, and Browser C picks 12pt
. Without an explicit set of values, browsers don't have to use the same point values for these keywords.
We might have been lucky, in that the browser vendors could have picked the same values for these keywords. Of course, we weren't, but the reason for this might surprise you. It involves legacy behavior under HTML, and the number of absolute-size keywords.
If you'll recall, there are seven absolute-size keywords. Under HTML 3.2, there were seven FONT
sizes (as in, FONT size="4"
). It would therefore seem to make sense that the seven keywords should map to each of the seven FONT
sizes. Unfortunately, that means the following:
1 | 2 | 3 | 4 | 5 | 6 | 7 |
---|---|---|---|---|---|---|
xx-small | x-small | small | medium | large | x-large | xx-large |
Note where medium
falls: on the number 4. Under HTML, however, the default FONT size
was 3-- so going by this table, "normal" text (being size 3) would correspond to small
, not medium
. This is what Internet Explorer does.
Navigator 4.x, on the other hand, assumes that medium
should be the same as "normal" (size 3) text. This is also quite reasonable, since one would naturally assume that the default value (medium
) should correspond to "normal" text.
Thanks to this basic discrepancy, setting the font size using any absolute-size keyword will guarantee inconsistent appearance between Explorer and Navigator. Take this example:
This is 12pt text. | This is medium text. | This is 14pt text. |
This is 10pt text. | This is small text. | This is 12pt text. |
In Navigator 4.x, the first two cells in each row should contain text of the same size; in Explorer, the second and third cells should have same-size text. The kicker is that neither is incorrect. For once, the inconsistency between browsers can't be blamed on one or the other, because both are compliant with the specification. They're just compliant in different ways.
Relative Sizes
There are two other keywords, both of which avoid being inconsistent. These are larger
and smaller
, and their effect is to bump the size of the font up or down, with respect to the parent element, using a consistent scaling factor (the specification recommends 1.2). Thus, given the following markup:
BODY {font-size: 12pt;} BIG {font-size: larger;} SMALL {font-size: smaller;}
...any text within a BIG
element will be about 14 points in size, whereas any SMALL
text will be about 10 points. Again, the exact sizes depend on the scaling factor used by the browser, but 1.2 seems to be used pretty consistently.
The danger here is that the changes in size are cumulative. Take this markup:
UL {font-size: smaller;}
This style will cause the font size of each UL element to be smaller than its parent element. Normally, that would be okay, but what happens when you have nested lists? Here's an example:
- This is a list item...
- ...and this one contains an unordered list:
- This is a list item...
- ...and this one contains an unordered list:
- This is a list item...
- ...and this one contains an unordered list:
- This is a list item...
- ...and this one contains an unordered list:
- plus another list item.
- plus another list item.
- plus another list item.
If your browser is CSS compliant, then what you should see is that each list is smaller and smaller, becoming progressively less legible. This is utterly correct behavior. The fact that the font size gets smaller with each list is exactly what the rule describes, and what the browser should do.
The primary advantage of using relative-size keywords is that they make everything work in relation to the user's default size preferences. They also allow the user to affect the size of all fonts. If a user has impaired sight, for example, and can't read some of your text, he can increase the default font size and have everything else increase in size along with it, while still maintaining the same relative sizes: SMALL
text will still be smaller than normal text, and so on.
The disadvantage, as we've seen, is that if you aren't careful, your text can quickly become too small to read, or too large to fit on a normal monitor. Think for a moment about what would happen to a page which relies on tables to lay out the text, and has this rule:
TD {font-size: smaller;}
If there is any nesting of tables, the text inside those tables will very quickly become illegible. Given the prevalence of table-layout pages, rules such as these must be used with the utmost caution, and you'll need to do a lot of testing before making your design public.
Better Sizing Through Structure
One possible workaround is to use contextual selectors to your advantage:
TABLE TD TABLE TD {font-size: smaller;}
This will not affect the size of text in the "first" table, but will make smaller
any text in the nested table. This absolutely relies on a very specific document structure, though, and could be a major problem if your page structure changes-- say, if another table is wrapped around the entire page.
A much better workaround is to assign a class to table cells which contain text that need to be smaller, something like this:
TD.aside {font-size: smaller;} <TD class="aside"> This cell's text should be smaller than its parent element's text. </TD>
This is a much better way to handle such things, and has the advantage of making your document's structure much stronger, so that you can apply other styles to such text if you desire.
Conclusion
As we've seen, for all their apparent simplicity, the use of keywords can be quite tricky. You need to always keep in mind how your styles will interact with each other, and what effect that will have on your users. Absolute-size keywords are easy to use, but introduce inconsistencies and suppress the user's ability to alter the size of the text. Relative-size keywords are usually a better way to go, but if you aren't careful, they'll make your page unreadable.
Next month, we'll look into two more ways of setting the size of your text-- length measures (such as points) and percentages-- and how they're quite similar to font-size
keywords in many ways. Until then, stay stylish!