15 Fonts


15.1 Introduction

Setting font properties will be among the most common uses of style sheets. Unfortunately, there exists no well-defined and universally accepted taxonomy for classifying fonts, and terms that apply to one font family may not be appropriate for others. E.g. 'italic' is commonly used to label slanted text, but slanted text may also be labeled as being Oblique, Slanted, Incline, Cursive or Kursiv. Therefore it is not a simple problem to map typical font selection properties to a specific font.

15.2 Font matching algorithm

Because there is no accepted, universal taxonomy of font properties, matching of properties to font faces must be done carefully. The properties are matched in a well-defined order to insure that the results of this matching process are as consistent as possible across UAs (assuming that the same library of font faces is presented to each of them).

  1. The User Agent makes (or accesses) a database of relevant CSS 2.1 properties of all the fonts of which the UA is aware. The UA may be aware of a font because it has been installed locally or it has been previously downloaded over the web. If there are two fonts with exactly the same properties, one of them is ignored.
  2. At a given element and for each character in that element, the UA assembles the font-properties applicable to that element. Using the complete set of properties, the UA uses the 'font-family' property to choose a tentative font family. The remaining properties are tested against the family according to the matching criteria described with each property. If there are matches for all the remaining properties, then that is the matching font face for the given element.
  3. If there is no matching font face within the 'font-family' being processed by step 2, and if there is a next alternative 'font-family' in the font set, then repeat step 2 with the next alternative 'font-family'.
  4. If there is a matching font face, but it doesn't contain a glyph for the current character, and if there is a next alternative 'font-family' in the font sets, then repeat step 2 with the next alternative 'font-family'. See appendix C for a description of font and character encoding.
  5. If there is no font within the family selected in 2, then use a UA-dependent default 'font-family' and repeat step 2, using the best match that can be obtained within the default font. If a particular character cannot be displayed using this font, then the UA has no suitable font for that character. The UA should map each character for which it has no suitable font to a visible symbol chosen by the UA, preferably a "missing character" glyph from one of the font faces available to the UA.

(The above algorithm can be optimized to avoid having to revisit the CSS 2.1 properties for each character.)

The per-property matching rules from (2) above are as follows:

  1. 'font-style' is tried first. 'italic' will be satisfied if there is either a face in the UA's font database labeled with the CSS keyword 'italic' (preferred) or 'oblique'. Otherwise the values must be matched exactly or font-style will fail.
  2. 'font-variant' is tried next. 'normal' matches a font not labeled as 'small-caps'; 'small-caps' matches (1) a font labeled as 'small-caps', (2) a font in which the small caps are synthesized, or (3) a font where all lowercase letters are replaced by upper case letters. A small-caps font may be synthesized by electronically scaling uppercase letters from a normal font.
  3. 'font-weight' is matched next, it will never fail. (See 'font-weight' below.)
  4. 'font-size' must be matched within a UA-dependent margin of tolerance. (Typically, sizes for scalable fonts are rounded to the nearest whole pixel, while the tolerance for bitmapped fonts could be as large as 20%.) Further computations, e.g. by 'em' values in other properties, are based on the 'font-size' value that is used, not the one that is specified.

15.3 Font family: the 'font-family' property

Value:  [[ <family-name> | <generic-family> ] [, <family-name>| <generic-family>]* ] | inherit
Initial:  depends on user agent
Applies to:  all elements
Inherited:  yes
Percentages:  N/A
Media:  visual

The value is a prioritized list of font family names and/or generic family names. Unlike most other CSS properties, values are separated by a comma to indicate that they are alternatives:

body { font-family: gill, helvetica, sans-serif }

Although many fonts provide the "missing character" glyph, typically an open box, as its name implies this should not be considered a match.

There are two types of font family names:

The name of a font family of choice. In the last example, "gill" and "helvetica" are font families.
In the example above, the last value is a generic family name. The following generic families are defined:

Style sheet designers are encouraged to offer a generic font family as a last alternative.

Font names containing whitespace should be quoted:

body { font-family: "new century schoolbook", serif }
<BODY STYLE="font-family: 'My own font', fantasy">

If quoting is omitted, any whitespace characters before and after the font name are ignored and any sequence of whitespace characters inside the font name is converted to a single space.

15.4 Font styling: the 'font-style' property

Value:  normal | italic | oblique | inherit
Initial:  normal
Applies to:  all elements
Inherited:  yes
Percentages:  N/A
Media:  visual

The 'font-style' property selects between normal (sometimes referred to as "roman" or "upright"), italic and oblique faces within a font family.

A value of 'normal' selects a font that is classified as 'normal' in the UA's font database, while 'oblique' selects a font that is labeled 'oblique'. A value of 'italic' selects a font that is labeled 'italic', or, if that is not available, one labeled 'oblique'.

The font that is labeled 'oblique' in the UA's font database may actually have been generated by electronically slanting a normal font.

Fonts with Oblique, Slanted or Incline in their names will typically be labeled 'oblique' in the UA's font database. Fonts with Italic, Cursive or Kursiv in their names will typically be labeled 'italic'.

h1, h2, h3 { font-style: italic }
h1 em { font-style: normal }

In the example above, emphasized text within 'H1' will appear in a normal face.

15.5 Small-caps: the 'font-variant' property

Value:  normal | small-caps | inherit
Initial:  normal
Applies to:  all elements
Inherited:  yes
Percentages:  N/A
Media:  visual

Another type of variation within a font family is the small-caps. In a small-caps font the lower case letters look similar to the uppercase ones, but in a smaller size and with slightly different proportions. The 'font-variant' property selects that font.

A value of 'normal' selects a font that is not a small-caps font, 'small-caps' selects a small-caps font. It is acceptable (but not required) in CSS 2.1 if the small-caps font is a created by taking a normal font and replacing the lower case letters by scaled uppercase characters. As a last resort, uppercase letters will be used as replacement for a small-caps font.

The following example results in an 'H3' element in small-caps, with emphasized words in oblique small-caps:

h3 { font-variant: small-caps }
em { font-style: oblique }

There may be other variants in the font family as well, such as fonts with old-style numerals, small-caps numerals, condensed or expanded letters, etc. CSS 2.1 has no properties that select those.

Note: insofar as this property causes text to be transformed to uppercase, the same considerations as for 'text-transform' apply.

15.6 Font boldness: the 'font-weight' property

Value:  normal | bold | bolder | lighter | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | inherit
Initial:  normal
Applies to:  all elements
Inherited:  yes
Percentages:  N/A
Media:  visual

The 'font-weight' property selects the weight of the font. The values '100' to '900' form an ordered sequence, where each number indicates a weight that is at least as dark as its predecessor. The keyword 'normal' is synonymous with '400', and 'bold' is synonymous with '700'. Keywords other than 'normal' and 'bold' have been shown to be often confused with font names and a numerical scale was therefore chosen for the 9-value list.

p { font-weight: normal }   /* 400 */
h1 { font-weight: 700 }     /* bold */

The 'bolder' and 'lighter' values select font weights that are relative to the weight inherited from the parent:

strong { font-weight: bolder }

Child elements inherit the resultant weight, not the keyword value.

Fonts (the font data) typically have one or more properties whose values are names that are descriptive of the "weight" of a font. There is no accepted, universal meaning to these weight names. Their primary role is to distinguish faces of differing darkness within a single font family. Usage across font families is quite variant; for example a font that you might think of as being bold might be described as being Regular, Roman, Book, Medium, Semi- or DemiBold, Bold, or Black, depending on how black the "normal" face of the font is within the design. Because there is no standard usage of names, the weight property values in CSS 2.1 are given on a numerical scale in which the value '400' (or 'normal') corresponds to the "normal" text face for that family. The weight name associated with that face will typically be Book, Regular, Roman, Normal or sometimes Medium.

The association of other weights within a family to the numerical weight values is intended only to preserve the ordering of darkness within that family. However, the following heuristics tell how the assignment is done in typical cases:

The following two examples show typical mappings.

Assume four weights in the "Rattlesnake" family, from lightest to darkest: Regular, Medium, Bold, Heavy.

First example of font-weight mapping
Available faces Assignments Filling the holes
"Rattlesnake Regular" 400 100, 200, 300
"Rattlesnake Medium" 500  
"Rattlesnake Bold" 700 600
"Rattlesnake Heavy" 800 900

Assume six weights in the "Ice Prawn" family: Book, Medium, Bold, Heavy, Black, ExtraBlack. Note that in this instance the user agent has decided not to assign a numeric value to "Ice Prawn ExtraBlack".

Second example of font-weight mapping
Available faces Assignments Filling the holes
"Ice Prawn Book" 400 100, 200, 300
"Ice Prawn Medium" 500  
"Ice Prawn Bold" 700 600
"Ice Prawn Heavy" 800  
"Ice Prawn Black" 900  
"Ice Prawn ExtraBlack" (none)  

Since the intent of the relative keywords 'bolder' and 'lighter' is to darken or lighten the face within the family and because a family may not have faces aligned with all the symbolic weight values, the matching of 'bolder' is to the next darker face available on the client within the family and the matching of 'lighter' is to the next lighter face within the family. To be precise, the meaning of the relative keywords 'bolder' and 'lighter' is as follows:

There is no guarantee that there will be a darker face for each of the 'font-weight' values; for example, some fonts may have only a normal and a bold face, others may have eight different face weights. There is no guarantee on how a UA will map font faces within a family to weight values. The only guarantee is that a face of a given value will be no less dark than the faces of lighter values.

15.7 Font size: the 'font-size' property

Value:  <absolute-size> | <relative-size> | <length> | <percentage> | inherit
Initial:  medium
Applies to:  all elements
Inherited:  yes, the computed value is inherited
Percentages:  refer to parent element's font size
Media:  visual

The font size corresponds to the em square, a concept used in typography. Note that certain glyphs may bleed outside their em squares. Values have the following meanings:

An <absolute-size> keyword is an index to a table of font sizes computed and kept by the UA. Possible values are:

[ xx-small | x-small | small | medium | large | x-large | xx-large ]

The following table provides user agent guidelines for the absolute-size scaling factor and their mapping to HTML heading and absolute font-sizes. The 'medium' value is used as the reference middle value. The user agent may fine tune these values for different fonts or different types of display devices.

CSS absolute-size values xx-small x-small small medium large x-large xx-large  
scaling factor 3/5 3/4 8/9 1 6/5 3/2 2/1 3/1
HTML headings h6   h5 h4 h3 h2 h1  
HTML font sizes 1   2 3 4 5 6 7

Different media may need different scaling factors. Also, the UA should take the quality and availability of fonts into account when computing the table. The table may be different from one font family to another.

Note 1. To preserve readability, a UA applying these guidelines should nevertheless avoid creating font-size resulting in less than 9 pixels per EM unit on a computer display .

Note 2. In CSS1, the suggested scaling factor between adjacent indexes was 1.5 which user experience proved to be too large. In CSS2, the suggested scaling factor for computer screen between adjacent indexes was 1.2 which still created issues for the small sizes. The new scaling factor varies between each index to provide better readability.

A <relative-size> keyword is interpreted relative to the table of font sizes and the font size of the parent element. Possible values are: [ larger | smaller ]. For example, if the parent element has a font size of 'medium', a value of 'larger' will make the font size of the current element be 'large'. If the parent element's size is not close to a table entry, the UA is free to interpolate between table entries or round off to the closest one. The UA may have to extrapolate table values if the numerical value goes beyond the keywords.

Length and percentage values should not take the font size table into account when calculating the font size of the element.

Negative values are not allowed.

On all other properties, 'em' and 'ex' length values refer to the font size of the current element. On the 'font-size' property, these length units refer to the font size of the parent element.

Note that an application may reinterpret an explicit size, depending on the context. E.g., inside a VR scene a font may get a different size because of perspective distortion.


p { font-size: 16px; }
@media print {
	p { font-size: 12pt; }
blockquote { font-size: larger }
em { font-size: 150% }
em { font-size: 1.5em }

15.8 Shorthand font property: the 'font' property

Value:  [ [ <'font-style'> || <'font-variant'> || <'font-weight'> ]? <'font-size'> [ / <'line-height'> ]? <'font-family'> ] | caption | icon | menu | message-box | small-caption | status-bar | inherit
Initial:  see individual properties
Applies to:  all elements
Inherited:  yes
Percentages:  allowed on 'font-size' and 'line-height'
Media:  visual

The 'font' property is, except as described below, a shorthand property for setting 'font-style' 'font-variant' 'font-weight' 'font-size', 'line-height' and 'font-family' at the same place in the style sheet. The syntax of this property is based on a traditional typographical shorthand notation to set multiple properties related to fonts.

All font-related properties are first reset to their initial values, including those listed in the preceding paragraph. Then, those properties that are given explicit values in the 'font' shorthand are set to those values. For a definition of allowed and initial values, see the previously defined properties.

p { font: 12px/14px sans-serif }
p { font: 80% sans-serif }
p { font: x-large/110% "new century schoolbook", serif }
p { font: bold italic large Palatino, serif }
p { font: normal small-caps 120%/120% fantasy }

In the second rule, the font size percentage value ('80%') refers to the font size of the parent element. In the third rule, the line height percentage refers to the font size of the element itself.

In the first three rules above, the 'font-style', 'font-variant' and 'font-weight' are not explicitly mentioned, which means they are all three set to their initial value ('normal'). The fourth rule sets the 'font-weight' to 'bold', the 'font-style' to 'italic' and implicitly sets 'font-variant' to 'normal'.

The fifth rule sets the 'font-variant' ('small-caps'), the 'font-size' (120% of the parent's font), the 'line-height' (120% times the font size) and the 'font-family' ('fantasy'). It follows that the keyword 'normal' applies to the two remaining properties: 'font-style' and 'font-weight'.

The following values refer to system fonts:

The font used for captioned controls (e.g., buttons, drop-downs, etc.).
The font used to label icons.
The font used in menus (e.g., dropdown menus and menu lists).
The font used in dialog boxes.
The font used for labeling small controls.
The font used in window status bars.

System fonts may only be set as a whole; that is, the font family, size, weight, style, etc. are all set at the same time.These values may then be altered individually if desired. If no font with the indicated characteristics exists on a given platform, the user agent should either intelligently substitute (e.g., a smaller version of the 'caption' font might be used for the 'small-caption' font), or substitute a user agent default font. As for regular fonts, if, for a system font, any of the individual properties are not part of the operating system's available user preferences, those properties should be set to their initial values.

That is why this property is "almost" a shorthand property: system fonts can only be specified with this property, not with 'font-family' itself, so 'font' allows authors to do more than the sum of its subproperties. However, the individual properties such as 'font-weight' are still given values taken from the system font, which can be independently varied.


button { font: 300 italic 1.3em/1.7em "FB Armada", sans-serif }
button p { font: menu }
button p em { font-weight: bolder }

If the font used for dropdown menus on a particular system happened to be, for example, 9-point Charcoal, with a weight of 600, then P elements that were descendants of BUTTON would be displayed as if this rule were in effect:

button p { font: 600 9px Charcoal }

Because the 'font' shorthand property resets any property not explicitly given a value to its initial value, this has the same effect as this declaration:

button p {
  font-style: normal;
  font-variant: normal;
  font-weight: 600;
  font-size: 9px;
  line-height: normal;