Becoming a Font Embedding Master

I've spent a couple days worth now trying to figure out the best and most complete approach to font embedding using @font-face . It really is a dark art that must be mastered. It is by no means a straightforward process.

Font Formats

Generally speaking, these days, a font on our system is going to be one of two formats: TrueType (with a .ttf file extension) or OpenType (with a .otf file extension). While it would be nice to be able to just throw a font like this on the web and link it up, we're hit with two major limitations.

Licensing, and Browser Support

Licensing

Licensing is one of the biggest hurdles. It can be difficult to find a font that really works within the overall aesthetic of a design. It's the reason we've had to resort to exporting images, sIFR or Cufon.

Even many free fonts have limitations on how they can be used, often times requiring specific directions on linking back to the original source or only using them in non-commercial sites.

These days, a number of resources are popping up—especially those dedicated to font embedding. A good start to finding the right font for your project would be Font Squirrel. Font Squirrel even provides @font-face kits to make implementation on your web site easy. However, even these kits don't provide as complete of browser support as what I'm covering here.

Browser Support

Which leads me into the other major issue, browser support. Font embedding with a TrueType or OpenType font only works as of Firefox 3.5, Safari 3.1, and Opera 10. (You can enable it in your copy of Chrome 2 by using a command line switch.)

Okay, that's decent already but we can do better. We can get Internet Explorer 4+, Chrome 0.3+, Opera 9+ and even a little mobile Safari action.

EOT

Internet Explorer supports a particular type of format called Embedded OpenType that provides some control over where and how the font is allowed to be embedded. You'll need to convert your TTF into an EOT format. Microsoft provides a tool called WEFT but it is ancient and I'll be damned if I can get it working. Thankfully, there is a command line tool called TTF2EOT that can convert your font.

If you have an OTF file, you'll need to convert it into a TTF file before you can convert it into an EOT. FontForge is the application that I use to do it and has provided me with the most consistent results. I urge you to check out my screencast on OTF to TTF conversion using FontForge as it is a surprisingly tricky process.

As you'll soon see, having the file in a TTF format will help us with the next step.

SVG

With TTF/OTF and EOT, we have decent browser coverage but the coup de grace is to add one more font format to the mix: SVG. SVG fonts are supported by Chrome 0.3+ without having to use a command line hack, along with Opera 9 and (with testing provided by the Twitter folk) iPhone OS 3.1. Additional mobile browsers may support it as well but I have been unable to get thorough confirmation on this.

FontForge has an option to export to an SVG format but I was seeing odd behaviour in Opera with missing characters. Alternatively (and thankfully!), I found a Java application that can be run from the command line called Batik. When running the conversion, you must specify the ID parameter. You won't get an error if you don't but the ID is important at the CSS stage.

java -jar batik-ttf2svg.jar ./MuseoSans-500.ttf -o museo.svg -id museo

One of the concerns in exporting to SVG is file size. Immediately I had noticed that my 29k font was now sitting in well over 100k. The biggest reason was the number of hkern elements that, I guess, are meant for kerning. (I'm smart like that.) However, you should be able to delete them without greatly impacting the display of your font but greatly impacting the file size. The other thing I noticed was glyph-name="null" on all of the glyph nodes. I was able to remove them with, once again, no impact to the display of the font. Having done so brought my SVG fonts to the point where they were smaller than the original TrueType font I had converted from (29k to 20k in one case and 18k to 12k in another case).

CSS

Now that we have our three files—TTF (or OTF), EOT and SVG—it is time to get our CSS mojo on. Starting with Paul Irish's bullet-proof base, I've added an additional entry for the SVG font.

@font-face { font-family: 'GothicCustom'; src: url("LeagueGothic.eot"); src: local('League Gothic'), url("LeagueGothic.svg#lg") format('svg'), url("LeagueGothic.otf") format('opentype'); }

The font-family name that you specify here is arbitrary and I like to choose a unique name to make it clear in my other declarations that I'm using an embedded font.

The SVG syntax has one particular thing of note, and that is the ID anchor after the font name. Specify the ID that you used when doing the SVG conversion. Alternatively, open up the SVG font and make sure that the font element has an ID.

<font id="lg">

Specifying font-family works as it normally would. Just specify the font name that you used in your @font-face declaration.

font-family: 'GothicCustom', 'Arial Narrow', sans-serif;

Subsetting

In the screencast, I gave a quick demo of how to subset a font by clearing glyphs that aren't to be used in the final font. Why would you want to subset a font? It makes the file smaller. Some font files can easily weigh in at 200k. That's a lot to download when people don't need to. For example, the masthead on this site is—as of this writing—using Museo Sans. A great font that weighs in at around 65k. Since the masthead only uses a limited set of characters, I was able to remove anything I didn't need and brought the file size down to 20k.

If you optimize your images, why not optimize your fonts?

Text Transform Bug

There is one caveat to be aware of when subsetting. In my case, I assumed that I could quickly do without most of the lowercase glyphs. A text-transform:uppercase statement was all I really needed.

<div>About</div> div { text-transform:uppercase; }

This works fine in Firefox and Safari but Opera and Internet Explorer both seem to decide whether to use a font for a particular character by looking at the lowercase character first. This meant it was using the uppercase characters from a fallback font. That's certainly less than ideal.

Of course, you can always just change the HTML source to be uppercase, if you were dead set on removing those glyphs.

Print Style Sheets

When I first set out to use @font-face , I didn't even foresee this added bonus: the custom fonts also work just fine with print style sheets. It wasn't like using image replacement techniques and having to fall back to a boring browser font for print. It felt good printing off a page of my site that still used the same fonts as what I saw on screen.

Never Going Back