

web developer guide

my books

Book cover of Pro CSS3 AnimationPro CSS3 Animation, Apress, 2013

my projects

tipster.ioAutomatically provides local tipping customs and percentages for services anywhere.

Embedding Fonts With CSS

css / typography

Estimated. reading time: 4 minutes, 45 seconds

Under CSS3, fonts can be embedded into web pages. That is, the end-user sees the page text in the font it is meant to be seen in, without needing the requisite typeface in their own fonts folder. However, this has several problems:

  1. Only CSS3-aware browsers support this feature. Perhaps surprisingly, Internet Explorer has supported embedded fonts since IE 5.5, via its own proprietary WEFT format.

  2. The font used must be available from a server. Local fonts sourced from your own hard-drive will not work.

  3. There has been a vociferous reaction from font foundries to this proposal. Traditionally, in order to see a font on a computer you have had to own it: fonts are software. In some variants of font embedding techniques, you are making the fonts available to everyone, which has legal ramifications.

  4. Embedding a font can add significant size to the page. While a simple font with limited character set coverage might be only 20K in size, a large one, such Helvetica, might weigh in at 2MB or more.

There are a number of solutions in place to address these problems. Mozilla has introduced the WOFF format, a compressed font format (answering point 4) containing ownership information (addressing some of the concerns of font designers raised in point 3).

All of this is still irrelevant and unnecessary if you are only using this particular font once, as in a logo. If that is the case, it is far more practical to make the logo into a bitmapped image, rather than embedding the font.

Assuming that you wish to use a particular font in body copy, how do CSS embedded fonts work?

The we are about to use, @font-face, recognizes fonts in OpenType (.otf), TrueType(.ttf), Web Open Font Format (.woff), Scalable Vector Graphics (.svg) and Embedded Open Type (.eot) formats. Fonts in other formats will need to be converted (and no, simply changing the extension on the end of the font file will not work). If your chosen font is not in one of these formats you can use an application such as DfontSplitter or Transtypeto to convert it. Alternatively you could use a service, such as OnlineFontConverter.

Once you have your chosen font in the correct format, you need to make it available to your web page. There are several ways of doing this: using a separate font hosting service, or by placing the font on your own server. (Of course this assumes you have the right to do either – I am using the font DejaVu Serif, an open source derivation of Bitstream Vera, for this demonstration.)

For this example, I’ll place a copy of DejaVuSerif.ttf in a fonts directory, located in my site’s assets folder. (Refer to this earlier entry if you need a refresher on site structure and organization).

Next, we have to refer to the font itself. This is typically done as the first declaration in a linked style sheet:

@font-face { font-family: DéjàVu Serif; src: url(fonts/DejaVuSans.ttf); }

The first property is used much as font-family is used in standard CSS: it is the name of the font as it appears in the drop-down menu of a word processor on our computer, assuming we have the font correctly installed. In CSS3, the font name used is a reference. We could (and will) set this to anything we like, but using the name of the font makes the most sense.

The next property used in the declaration, src, points the browser to where the font resides on the server. Its value has the same format as background-image, list-style-image, and other properties we have used in the past.

We then use the reference name in our font declaration, as the first choice in a typical font stack:

h2 { font-family: DéjàVu Serif; }

It makes sense to extend this using the standard CSS font stack techniques we have discussed earlier. In this case, the stack I would suggest is:

h2 { font-family: DéjàVu Serif, Bitstream Vera Serif, Georgia, Hoefler Text, Times New Roman, Times, serif; }

Finally, upload the chosen font to the fonts folder on your server. Then upload a page that uses the <h2> element to a server, along with an associated stylesheet, and test the page.

This approach has one problem: under this declaration, a CSS3-aware browser will always download the font from the server, even if the user has their own copy of the typeface in the fonts directory of their computer. To get around this, we can specify a preference to look in the local fonts folder first; if the font cannot be found there, then download the font:

@font-face { font-family: DéjàVu Serif; src: local("DejaVu Serif"), url(fonts/DejaVuSans.ttf); }

This declaration gracefully degrades in CSS. A browser only aware of CSS Levels 1 and 2 will look for fonts present in the user’s font folder and find the first font that matches the order given in the font stack. If the browser is supports embedded fonts, it will download and use the font from the server (the user will not retain a permanent copy of the font).

To test that the font is being used correctly, change the font-family reference name in the stylesheet to a word that does not refer to any fonts installed on your system:

@font-face { font-family: "foobar"; src: url(fonts/DejaVuSans.ttf); }
h2 { font-family: foobar, Bitstream Vera Serif, Georgia, Hoefler Text, Times New Roman, Times, serif ; }

If the h2 text still appears in the DejaVu Sans font on your page, you have proven that the font is correctly embedded, and is not reading from the fonts directory on your computer. (Of course, you should change it back in the stylesheet after testing this).