Wednesday, August 5, 2009

The @font-face at-rule

The @font-face rule can be used for a number of things:

  1. Fonts that are not commonly provided by operating systems can be used on a webpage. The font files are downloaded by the browser when the page is loaded.
  2. Can be used to give simpler names to operating system fonts
  3. Operating system font-family names can be re-assigned to downloadable font files.
  4. Multiple font locations can be specified. Therefore, if a particular font is not provided by the viewer's operating system, only then will the browser download the font from the server.
  5. Complete font-families containing a boldface font, an oblique/italic font, and multiple weights can be created using @font-face.
  6. Special downoladable fonts such as light or oblique/italic can be specified for operating system font-families.
General Syntax

The general syntax of an @font-face rule is:
@font-face { descriptor: value }
Here is an example of an @font-face rule:
font-face {
font-family: Example;
src: url(http://www.example.com/example.ttf)
}

In the example, font-family and src are descriptors and Example and url(http:/www.example.com/example.ttf) are values. The descriptor, the colon and the value together are called font-descriptors.

The font-family Descriptor

Every @font-face rule must have the font-family descriptor. The font-family descriptor's value specifies the name of the font family for which the subsequent font descriptions apply. The value of font-family can also be the name of an operating system font family, in which case the font description will override the default properties of the font family.

Here is an example of the font-family descriptor:

font-family: "Example Modern";

The src Descriptor

The src descriptor indicates the location of the font file associated with the font family name and, optionally, a format hint of the font file. The location of the file can be indicated by a URL or, if the font is provided by the operating system, by the font family name. ; An @font-face rule can have only one src font-descriptor.

In an @font-face rule, the value of the src font descriptor can be a comma separated list of sources. If the font file cannot be found at the first location, the browser will try the second location.

Here is an example of the src font descriptor with only one location specified:
@font-face {
font-family: "Example Modern";
src: url(http://www.example.com/example.ttf) format("truetype")
}

The src descriptor can also point to a "local" font. A local font is the name of a font that is provided by the operating system.

Here is another example with two locations specified:
@font-face {
font-family: "Example 1";
src: local("Example 1"), url(http://www.example.com/example_1.otf)
}


Format Hints

The format hint consists of the word format followed by the font file format name in quotes, inside parentheses. The whole expression appears at the end of a url location in the src font-descriptor.
The format hint will tell the browser what format the font file specified in url is. Based on that information, the browser can avoid downloading unsupported font files.

Here is a table of currently defined format hints:

Format Hint Font Format File extensions
"truetype" TrueType .ttf
"opentype" OpenType .ttf, .otf
"truetype-aat" TrueType with Apple Advanced Typography extensions .ttf
"embedded-opentype" Embedded OpenType .eot
"svg" SVG Font .svg, .svgz

The format hints "truetype" and "opentype" are considered equivalent to each other.


Embedded OpenType (eot)

Internet Explorer 6, 7 and 8 only support embedding of fonts in Microsoft's Embedded OpenType (eot) format. Eot files are not supported by other browsers. Eot files can be created from font files that have the ttf extension. Therefore, eot files can be created only from TrueType font files and OpenType TT font files, not OpenType PS (.otf) files. The open source application fontforge can be used to convert otf fonts to ttf in order to convert them to eot.

Eot files are compressed and also allow restricted access — a root url is specified when creating the eot file and the browser will only load the eot file from html pages that are below the specified root url. An eot file can either contain all the glyphs contained in a font file or only the glyphs that were selected at the time of creation of the eot file (subsetting).

Eot files can be created using Microsoft's Web Embedding Fonts Tool (WEFT) or the open-source ttf2eot. While ttf2eot is much easier to use than WEFT, it can only convert a ttf file to eot — it does not support subsetting and domain restriction.

Here is an example of the CSS code to embed an eot font file:
@font-face {
font-family: "A Yummy Apology";
src: url(http://www.example.com/yummy.eot);
}

font-style with @font-face

The font-style descriptor can be used to specify the oblique or italic fonts of a font-family. All major browsers consider oblique and italic as equivalent. Therefore, it is not currently possible to specify both an oblique and an italic font in a font-family.

Here is an example of how @font-face can be used to specify both a normal and oblique/italic font for a downloadable font-family:
@font-face {
font-family: "Example 1";
src: url(http://www.example.com/example_reg.ttf) format("truetype");
}
@font-face {
font-family: "Example 1";
src: url(http://www.example.com/example_italic.ttf) format("truetype);
font-style: italic;
}

font-weight with @font-face

The font-weight descriptor can be used to specify fonts for different font weights of a font-family.

Example 1:
@font-face {
font-family: "Example 2";
src: url(http://www.example.com/example2_reg.ttf) format("truetype");
}
@font-face {
font-family: "Example 2";
src: url(http://www.example.com/example2_bld.ttf) format ("truetype");
font-weight: bold;
}

Example 2:
@font-face {
font-family: "Example";
src: url(http://www.example.com/example_reg.ttf) format("truetype");
}
@font-face {
font-family: "Example";
src: url(http://www.example.com/example_lig.ttf) format("truetype");
font-weight: 100;
}
@font-face {
font-family: "Example";
src: url(http://www.example.com/example_med.ttf) format("truetype");
font-weight: 200;
}

font-stretch with @font-face

The font-stretch descriptor can be used to specify the fonts to be used for different font widths within a font-family. However, the font-stretch property is currently not supported by any major browser.

Example:
@font-face {
font-family: "Example";
src: url(http://www.example.com/example_reg.ttf) format("truetype");
}
@font-face {
font-family: "Example";
src: url(http://www.example.com/example_cond.ttf) format("truetype");
font-stretch: condensed;
}
@font-face {
font-family: "Example";
src: url(http://www.example.com/example_expa.ttf) format("truetype");
font-stretch: expanded;
}

Browser Support

Firefox 3 and Opera 9.6

Firefox 3 and Opera 9.6 do not support @font-face. They completely ignore it.

Firefox 3.5, Safari 3.2.3 and Safari 4

Firefox 3.5, Safari 3.2.3 and Safari 4 fully support @font-face. However, there are some small differences between them in terms of feature implementation.
Firefox 3.5 only allows relative links in url specifications. Therefore, by default, the font files cannot be in another domain. This restriction can be relaxed using HTTP Access Controls. No other major browser implements such a restriction.
Safari 3.2.3 does not support number font-weights.
If a normal font is specified in an @font-face rule containing font-weight: bold or a font-weight of 600, 700, 800 or 900, Safari 3.2.3 and Safari 4 simulate bold face when rendering the text that the font is applied to. Firefox 3.5 does not.
Similarly, Safari 3.2.3 and Safari 4 simulate slanted text when using a normal font specifed by an @font-face rule for slanted/oblique text. However, Firefox 3.5 does not.
Eot files are not supported by any of these browsers.

Chrome 2

Chrome 2 partially supports @font-face — it does not support downloading of font files but supports all the features of @font-face with operating system (local) fonts.
If a normal font is specified in an @font-face rule containing font-weight: bold or a font-weight of 600, 700, 800 or 900, Chrome 2 simulates bold face when rendering the text that the font is applied to. Similarly, Chrome 2 also simulates slanted text when using a normal font specifed by an @font-face rule for slanted/oblique text.
Eot files are not supported by Chrome 2.

Internet Explorer 6, Internet Explorer 7 and Internet Explorer 8

Internet Explorer 6, Internet Explorer 7 and Internet Explorer 8 have basic support of @font-face with eot files. They do not support ttf and otf files. They only support simple @font-face rules that download eot files. They ignore the following:

  • @font-face rules that have format hints
  • @font-face rules with more than one location
  • @font-face with font-stretch

Firefox 3.5, Safari 3.2.3, Safari 4, Chrome 2, Internet Explorer 6, Internet Explorer 7 and Internet Explorer 8 do not support font-stretch in @font-face rules.

Tips

Internet Explorer 6, Internet Explorer 7 and Internet Explorer 8 download ttf and otf fonts specified in @font-face rules even though they do not support them. To prevent this, always use format hints when specifing ttf and otf fonts in @font-face rules.


When using a downloadable font in a web page, to ensure that both users of Internet Explorer and other browsers get to see the text in the correct font, one should have both a ttf/otf file and an eot file.

The @font-face rule for the eot file should appear before the @font-face rule for the ttf/otf file. This ensures that the appropriate file is loaded in Internet Explorer and other browsers.

Example:
@font-face{
font-family: example;
src: url(yummy.eot)
}
@font-face{
font-family: example;
src: url(yummy.ttf) format("truetype");
}


Both Microsoft's Web Embedding Fonts Tool (WEFT) and the open-source ttf2eot can only convert ttf fonts to eot. Therefore, it is necessary to first convert otf fonts to ttf in order to convert them to eot. The open source application fontforge can be used for this purpose.


The official w3.org specification of @font-face can be found here.

2 comments:

george said...

Having 2 @font-face selectors isn't best. (IE tries to load the 2nd font and generates a 404 - file not found).

Here's a tutorial that uses stronger CSS.

Chetan Crasta said...

@george: Thanks for the link.

It appears IE does not ignore src declarations with format hints — instead, it mangles the URL and therefore fails to download the file. This generates the 404 error at the server. Note, however, that this does not affect the viewer of the page.

Here is the link to the original article http://paulirish.com/2009/bulletproof-font-face-implementation-syntax/