CSS @font-face: Cross-Browser Font Support
In 2007, the W3C released the
CSS Fonts Module Level 3, which introduced a number of new font features into the venerable CSS specification, including CSS selectors that start with the ampersand (
@) character. One of the more significant new directives was
@font-face. This directive lets a web designer link to a local font and give it a useful work name, which adds it to the list of recognized fonts for the renderer and makes it possible to use the font directly in a web page.
The syntax for @font-face is relatively simple:
@font-face {
font-family: myFontFamilyName;
src:[url(urlToFontResource) [format("truetype|truetype-aat|opentype|embedded-opentype|svg")][,]]*
}
For instance, for the Scythe font, my directive looked like:
@font-face {
font-family: "Scythe";
src:url("/sites/default/files/scythe.ttf") format="truetype";
}
The optional format() property provides a hint to the system about the specific format that the font uses. If you don't include format(), the browser can usually figure the type out on its own, but that can add to the overall processing time required to display the font. Apple uses the "truetype-aat" format (aat stands for "Advanced Apple Typography" extensions), while "embedded-opentype" is Microsoft's .EOT format and "svg" is a reference pointer to an SVG glyph library.
Given that different platforms may use different formats, the directive can include multiple definitions for the same font-face:
@font-face {
font-family: "Scythe";
src:url("/sites/default/files/scythe.ttf") format("truetype"),
url("/sites/default/files/scythe-aat.ttf") format("truetype-aat"),
url("/sites/default/files/scythe.eof") format("embedded-opentype"),
url("/sites/default/files/scythe.svg#font") format("svg");
}
Additionally, some fonts contain multiple representations in the same resource (say, a TTF file that contains both the base TTF format and AAT extensions). In this case, the format statement can take multiple comma-separated arguments:
@font-face {
font-family: "Scythe";
src:url("/sites/default/files/scythe.ttf") format("truetype, truetype-aat");
}
When the family is defined, you can use it in exactly the same way that you would any other font-family. For instance, for the headings on my site, I set the CSS to try using the Scythe family first, then to fall back to Times New Roman:
h1, h2, h3, h4 {font-family:"Scythe","Times New Roman",serif;}
Again, as with regular CSS, the quotes are optional if the term is only a single word, but using them usually is a good practice.
In some cases, the TTF files that you have available may be broken up into different weight or obliqueness fonts. Rather than having the browser use its usual rendering rules from the base type (i.e., expanding each font glyph horizontally for bold or applying a skew to the glyph for oblique), you can use additional @font-face directives to add in the appropriate fonts when the time calls for it:
@font-face {
font-family: "Scythe";
src:url("/sites/default/files/scythe.ttf") format("truetype, truetype-aat");
}
@font-face {
font-family: "Scythe";
src:url("/sites/default/files/scythe-italic.ttf") format("truetype, truetype-aat");
font-style: italic;
}
@font-face {
font-family: "Scythe";
src:url("/sites/default/files/scythe-bold.ttf") format("truetype, truetype-aat");
font-weight: bold;
}
@font-face {
font-family: "Scythe";
src:url("/sites/default/files/scythe-bolditalic.ttf") format("truetype, truetype-aat");
font-style: italic;
font-weight:bold;
}
Thus, if you use the Scythe later in conjunction with font-style italic:
@h1 {font-family: "Scythe";font-style:italic;}
The browser will render the text with the scythe-italic.ttf font rather than using a default algorithm, which results in cleaner text output in most cases.
As with most CSS changes, the @font-face directive has taken a while to percolate into web browsers:
- Microsoft has supported @font-face as of IE 5.
- Opera's support for @font-face landed in Opera 10.
- Firefox has it as of 3.5.
- Safari has had it since 3.2.
- Chrome also supports @font-face internally, but this option was disabled because of a potential security vulnerability for TTFs. You can set Chrome to recognize font-face by using the --enable-remote-fonts flag from the command line. If you're running Linux Chromium, use chromium-browser --enable-plugins --enable-remote-fonts %U. Chrome is expected to re-enable @font-face with the next major release.
Always Have a Fallback Font
At this stage, you should view fonts delivered via
@font-face the way you do accentssomething that you can enable for most web viewers, but that you also provide fallbacks for in case the user's browser doesn't support
@font-face. You usually will place
@font-face anywhere you'd normally place
font-family. Thus, in my code, I made sure that I included a fallback font ("Times New Roman") and a fallback for that ("serif"):
@h1 {font-family: "Scythe","Times New Roman",serif;}
For all that, however, the (re-)emergence of user-supplied fonts on the web should present a great deal of opportunities for web graphic designers (as well as open up the possibility for visually horrendous designs, but that's usually the price of innovation). Coupled with other useful features of CSS 3.0such as columnsthat are (finally) making their way into mainstream browsers, user-supplied fonts hopefully will affect a shift towards a visual style that marries the best features of both web and print media.