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.

  1. Licensing, and
  2. 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

Despite the frustration, I've come to the conclusion that—if the design called for it—I'd rely on @font-face over sIFR and Cufon. I really prefer not having to use JavaScript and I enjoy all the other benefits that come from using @font-face. I certainly look forward to the future when all of these headaches are no longer necessary.

Published October 07, 2009
Categorized as HTML and CSS
Short URL: http://snook.ca/s/957

Conversation

92 Comments · RSS feed
Michael Stanford said on October 07, 2009

Amen, friend. I'll definitely be using this (or attempting to) in an upcoming project of mine. Thanks for all the great advice.

Paul Irish said on October 07, 2009

Whoa, mega-post. This is solid work, Jonathan. This'll be very useful.

It's great to see SVG fonts get their proper respect here. For those that are interested, Divya Manian has done some great research on SVG fonts.

Did you manage to get a list of the mobile webkit agents that support SVG @font-face?

Matt Wiebe said on October 07, 2009

Thanks for the thorough rundown! I had no idea about SVG fonts, but I'll definitely have to include them in the arsenal from now on.

Jonathan Snook said on October 07, 2009

@Paul: Unfortunately, the only reliable mobile webkit test was iPhone OS3.1. I had one report of a "Nokia N900 prototype (running Maemo 5 w/ a mobile Firefox build)" that was successful. I emailed PPK to see if he was up for the challenge if I provided him a test case. Hopefully we'll have something more concrete in the coming days.

Trent Walton said on October 07, 2009

Dark art indeed... what a great, comprehensive write-up. I haven't taken @font-face any further than Safari & FF3. You've raised the bar.

Evan Stein said on October 07, 2009

A giant leap for @font-face. Thanks!!

Bennie Mosher said on October 07, 2009

Quite marvelous if I do say so myself! Probably the best tutorial and blog post on font replacement. Say goodbye to Javascript font replacement for me! Thank you very much for this post!

Bennie Mosher said on October 07, 2009

Jonathan,

I thought that I would let you know what a friend of mine let me know. When looking at your site in Chrome 3.0.195.25 on Windows 7 your title's look like this:

<img src="http://dev.benniemosher.com/font.jpg" alt="Broken Title" />

I thought that I would let you know so that you can fix it.

Adriaan said on October 07, 2009

It still seems like a lot of work to add custom fonts to your site - I wish it was easier...

sophy said on October 08, 2009

This good for my language that small use in the world. thankx

Jeremy Ricketts said on October 08, 2009

I found that really helpful. Thanks man!

Lars said on October 08, 2009

This looks great, but one comment though:

I've tested it in FF, IE, Safari, Chrome and Opera (9.64).
Except from Opera all work great.

In Opera 9.64 it actually falls back to the Impact-font.

Any ideas about that one?

Nelson Menezes said on October 08, 2009

I second Lars above... Opera 9.64 on Ubuntu here... no luck. Works beautifully on Opera 10 though.

Tom said on October 08, 2009

Wow, another font file to throw into the fray? TTF and EOT are fine, but an extra SVG? I guess I need to try it in practice to see if it's worth it, but none the less: A great find and great write up!

Paul Olyslager said on October 08, 2009

Finally a good overview of the possibilities of fonts in the different browsers. Thank you.

Pete B said on October 08, 2009

Should add my name to the previous comment :)

prisca said on October 08, 2009

brilliant post :)
Been trying to find some time to play around with font embedding... but does all seem quite drawn out - now I know where to start, right here.
Thanks for a great write up :)

Christoph Sasse said on October 08, 2009

I just want to thank you for taking all of this testing-pain and then share the good stuff with us. I hope this will lead to elegant ways for @font-face-embedding.
Soon we might say: "There's an app for that."

פורומים said on October 08, 2009

Excellent! I'm going to study this a little further with all the great material you posted

Ed Melly said on October 08, 2009

Thanks for such a helpful article. I've adopted Paul Irish's syntax and tried to use @font-face here. It works perfectly in ie and locally in ff, but for some reason won't work on the live site in ff.

Does anyone know if there are any server issues/permissions that need to be set to get otf files working from a Windows server? Or - more likely - have I just got something wrong?

Ethan Dunham said on October 08, 2009

I'll take that Font Squirrel comment as a challenge, Jonathan. SVG support and subsetting coming soon... :-)

Jonathan Snook said on October 08, 2009

@Bennie Mosher: Thank you for the screenshot. It looks like something is very off. :) I'll have to see why that is. I hate when one browser feels like throwing it all off.

@Lars: I have to admit that I didn't test in Opera 9 so it's certainly possible that it's not supported. I took Wikipedia at face value. Nelson seems to confirm that. I'll update the post when I get a chance.

@Ethan Dunham: Please take it as a challenge! :) I'd love to see a one-stop shop for full font-face kits (as I'm sure plenty of other people would).

Greg Gamel said on October 08, 2009

This is solid work Jonathan! Thanks a million for providing the results freely. In future font-embedding projects, I'll definitely refer to this list.

Here's another hoping that PPK can provide results about mobile devices + font embedding. That would be superb!

Thanks again!

Bonfield said on October 08, 2009

Nice post! I spent some time adding an @font-face the other day after watching your screencast, and felt like I learned a ton, but ended up falling back to Cufon after i found the serif font I wanted rendered like crap on IE in particular but also a little funky on some other Win browsers. Font-sizes weren't terribly small at 18px and 14px.

The san-serifs did okay.

Wondering if you found issues with that, and did something pre-@font-face or other?

Again, thanks My Man for sharing.

Andy said on October 08, 2009

What, no cred for the SVG thing?

Steve said on October 08, 2009

too much work. i'll stick with cufon for now.

Jonathan Snook said on October 08, 2009

@Bonfield: I haven't seen fonts rendering too poorly but I have chosen fairly straightforward fonts. It's quite possible that additional hinting information is being lost, causing it to display poorly in IE. I don't have any specific workaround for that.

@Andy: Sorry to slight you. It was unintended. Did you do the write up to the article you linked up from my last post? If so, thank you. It's where I found the Batik converter. I tried to clarify in this post that SVG isn't necessarily smaller without some additional work. Further optimizations to the TTF could also be made to improve file size, too (I don't believe I removed the hinting in my fonts).

Harsha M V said on October 08, 2009

awesome post. thanx

Jeremy said on October 08, 2009

Very complete article. I never got the Microsoft tool to work either, and I don't like that command line program. Instead, I use http://ttf2eot.sebastiankippe.com although I don't know if uploading licensed fonts on there is very legal.

Andy said on October 08, 2009

@Jonathan: Yes, I did.

Also, I converted the font in full from TTF and the SVG ended up half the size of its TTF counterpart. I guess this could be coincidental and specific to that font. Either way, I would not recommend anyone to use the fonts without first optimizing them, of course.

Linus said on October 08, 2009

Why SVG? OpenType seems to do the job in all browsers but IE?

Manuel said on October 08, 2009

Very very cool! Thank you for this article and for explaining how SVG fonts are embedded.

@Linus: As was mentioned in the article, SVG fonts are supported in Chrome .3+ and Opera 9. If you're happy with the cutting edge browsers, you don't have to worry about this.

Furthermore, SVG is just cool, so having another use case more really rocks. And my personal measuring on GaramondNo8 (GPL font) shows me a saving of 308kB in file size from the TTF to the SVG version. *That's* a reason for switching, and I didn't even remove the hkern elements.

Cheers,

Manuel said on October 08, 2009

... I should explain my last figure: I use all four TTFs, Regular, Medium, Italic and MedIta. On summary, and after converting the TTFs to SVG the fonts have lost the 308kB all together.

Jerry said on October 08, 2009

I just spent a few days doing a custom WordPress job for a friend. When I was done I was real excited that it looked so good in all the browsers on my machine. When I looked at it on my backup machine, not so much. The title font really made the top of the page, and when that went away... I'm gonna try your advice. Good timing on this article for me.

Minneapolis Web Design Guy said on October 08, 2009

great and through article! Fonts have long been a design element that a lot of firms are ignorant on. Just happened to stumble upon this site, bookmarked now! Thanks for the info.

Cyprian Gwóźdź said on October 08, 2009

Great feeling of Time.
Thanks - I was just looking for this information and you wrote this post yesterday.

Vaughan Risher said on October 08, 2009

Great work... but I will definitely stick to Cufon - it's just so easy and I'm a Javascript addict.

Divya said on October 08, 2009

@linus If you want to know about the drawbacks of existing font formats, I wrote a bit on that.

Andy said on October 08, 2009

@Manuel: Actually, Opera 9 does not support SVG fonts for @font-face. Opera 10 does.

Joe said on October 08, 2009

Any word on the legal implications? If I take a legally purchased font and convert it for embedding purposes am I opening myself up to legal trouble from the font creator?

Jonathan Snook said on October 08, 2009

@Linus: There's two reasons why I'd include SVG: 1. smaller file and 2. iPhone.

@Joe: Every font is different. If you've had to pay money for it, it'll more than likely not support embedding (that means none of the stuff I've described here is allowed).

old9 said on October 08, 2009

seems won't be rendered by gdi++

Victory said on October 09, 2009

You did a lot of really great leg work here. This will definitely be my jumping off point for adventures in font-face land.

Chris L said on October 09, 2009

I seem to find that the @font-face seems to render find rather chunky. If anyone can help me figure out how to get them to render smooth, I will be in your debt. Thanks!

Pedro Almeida said on October 09, 2009

Very nice Post.

Branden Silva said on October 09, 2009

Excellent. *Muhahaha* I feel like a mad scientist learning this black magic. Definitely bookmarking this to play around with some time.

Zoltan Hawryluk said on October 09, 2009

Good to know about the SVG option. Will be interesting to compare to see how they render compared to TTF, OTF and EOT on the various browsers.

Thanks for this!

Bengacreative said on October 09, 2009

Thanks for the elaborate overview. I've known about sIFR , but it was good to learn about the other options that are out there.

Benga creative

Aaron Gustafson said on October 09, 2009

Inspired by this post, I built an extension, using eCSStender, to support a simplified @font-face syntax. It's rough right now and probably needs a little work still, but it gets the idea across: http://github.com/easy-designs/eCSStender.font-face.js

Ethan Dunham said on October 09, 2009

Ok guys, if you are willling to beta test, try the new Font Squirrel @font-face kit generator. You upload as many fonts as you want, and it churns out CSS, HTML, EOT, SVG plus your original fonts, all subsetted for the English language. Let me know if you find any bugs. GUI is still under construction.
http://www.fontsquirrel.com/fontface/generator

Torsten said on October 10, 2009

Thank you for that, great information. Keep your effort up!

Torsten said on October 10, 2009

Thank you for that, great information. Keep your effort up!

Julian said on October 11, 2009

I just visited your web site in Firefox 3.5 (running in Windows Vista), and (presumably due to loading the embedded fonts) it seemed to freeze my whole computer for about 30 seconds (including freezing the mouse). Quite concerning if you are not expecting it. Has anyone else experienced this?

Jamie said on October 12, 2009

This is a really great article with a lot of useful information for people who would want to give this a go. Thanks for sharing.

Rob Company said on October 12, 2009

@julian... er nope, its fine on mine. But then I'm running XP.. maybe its a Vista issue.

Emma Smyth said on October 12, 2009

Hey, thanks for the post, I enjoyed reading it, keep up the good work, also had a sneek peek at your portfolio, looking good :)

Martyn - Bristol Wesite Design said on October 12, 2009

Great post, you always see rticles based on the @fontface but it never goes into enough detail. great article and il be checking your site more often if you produce posts like this.

Martyn - Bristol Wesite Design said on October 12, 2009

Great article, you always see tutorials on @fonface but they never go in to really detail. if this is the quality of posts you offer regularly I'll be back.

PSD to HTML said on October 12, 2009

great article! It seems everything works great on IE6 that is really a pain when it comes to sIFR and Cufon.

Mark Guadalupe said on October 12, 2009

Great read, and becoming a 'Font Embedding Master' is a time worth spent, congratulations.. it's a job very well done..

Mike said on October 13, 2009

This is probably THE single best article I have read that summarizes the @font-face attributes to deal with the various browsers. So far I've had to put this information together on my own (and have come to the same result, except for the SVG option, which I just started investigating today).

All's well so far, EXCEPT that I can't get the SVGs to display in CHROME 3.x what-so-ever. I know that SVG should be working, based on the demo here: http://devfiles.myopera.com/articles/751/SVGfonts_in_HTML.html

Any ideas as to why Chrome would not render these out? I also tested it using FontSquirrel, a great site, btw, and it wouldn't work with the font kit provided, either!

Mike said on October 13, 2009

I noticed something: you can test if your SVG font works by browsing directly to it in Chrome. I noticed that none of my fonts would display, while other SVG sets I downloaded did in fact work!
I will have to resort to locating fonts that work in SVG as well - I have a strong suspicion that the free fonts I was using had many overlap errors and other issues, and as such didn't export properly to SVG.

Mike said on October 13, 2009

Sorry to keep updating in the comments like this - I hope it's not too much.
I identified why some SVG fonts will not render: the all-important DOCTYPE in the SVG file.

FontForge created this DOCTYPE:
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >

This did not render. After downloading and instpecting a working SVG font, it turns out that it did not have a DOCTYPE. After removing the DOCTYPE from my own SVG files, they all render out.

Now, I'm not exactly sure what the implications of this are. Can anyone elaborate on this?

Ethan Dunham said on October 14, 2009

Mike, thanks for discovering this bug!

Alan Ayoub said on October 14, 2009

Great article Jonathan, I've been researching this recently myself. Still on the fence as to whether ill use it or not. Steve Souders does bring an interesting argument.

Ethan Dunham said on October 14, 2009

The fontsquirrel.com @font-face generator now removes the doctype from the svg fonts it renders. I also made sure that all fonts it generates have a proper NAME table. I guess malformed ones are screwing up Firefox.

Jonathan Snook said on October 14, 2009

This really is a dark art. Thanks everybody for finding all the quirks in this conversion process and good job Ethan for getting all of this integrated into the converter. Sweet stuff.

joram Oudenaarde said on October 16, 2009

One thing I noticed with the @font-face tag, is that when you zoom in on text in Safari ( not sure if it's the same in Firefox and such), it blinks for a second.

So let's say you used a special font for your headers (like in your case Jonathan).
- Zoom in, and I noticed that it blinks back to Times for a second before showing the increased size of the @font-face font.

I'm on the latest version of Safari, but it was very noticeable. Not sure if this is because of the way some people use the @font-face tag, or a bug in html5, or simply something in Safari itself, but it's a bit strange :)

Having said that, I can't wait to have this see implemented in all browsers though... the idea of being able to use this tag without fear is very appealing :)

csscoffee said on October 16, 2009

This is awesome @snook, i will be grabbing this for the next project of mine
I really love your design :)

Andreas said on October 17, 2009

Thx very much.

In-80-days said on October 17, 2009

Thanks for this... This motivates me to use it on my next project

Patrick said on October 19, 2009

Opera 10 has a strange bug. It only works with one tab open, not with the others. See my little Screenr sceencast:
http://screenr.com/bWN

Graham Bradley said on October 20, 2009

Fantastic stuff, I've been dying to ditch sFIFR and I have a feeling this will be the push I need. Thanks Jonathan.

Jonathan Snook said on October 20, 2009

@Patrick: I check out your screencast and that's an absolutely bizarre bug. I can only imagine that this is something that Opera will need to get fixed.

Andy said on October 20, 2009

@Jonathan: I've already reported that bug to the Opera developers through Mark Pilgrim.

Graham Bradley said on October 23, 2009

I used this tutorial for my latest project and it worked a charm (although I had to use FontForge as Batik threw an exception for me). Again, thanks.

Nathan said on October 26, 2009

Is there anyway to do this without fontForge? For the life of me I cannot figure out how to install x11 from the cygwin website site and fontforge does not work without it. Any programs similar to fontforge that can be used? Really dying to try this out.

Montana Flynn said on October 26, 2009

Letter Spacing is also an issue in Safari 4 at least. If you have a :hover on text with letter spacing the hover will be cut short very slightly.

Aeron said on October 27, 2009

Thanks! Great to be able to reduce the declaration down to a single statement... my only comment would be to normalize your single and double quotes!

Minneapolis Designer said on October 28, 2009

Thanks for adding value to the design community. I've had a chance to look at a few of your post and they have all been spot on.

Thomas said on October 29, 2009

Wow man that's some great research!
I'll try this out in the near future!

John Pitchers said on November 01, 2009

Does this mean that Explorer does in fact support @font-face - but only with EOT font files? I was always under the impression that IE didn't support @font-face at all.

Aaron Peters said on November 03, 2009

Fyi: Opera Mobile supports @font-face with (at least) TTF fonts as of version 9.7. http://dev.opera.com/articles/view/opera-mobile-9-7-features-standards/. Scroll down to "Web fonts - Web typography just got easier".

Opera Mobile homepage: http://www.opera.com/mobile/

Wouter Vermeulen said on November 03, 2009

Why do you use sometimes double quotes and sometimes single quotes in your CSS code?? Does that serve any purpose, or just accidentally?

Many thanks,
Wouter Vermeulen

Victor said on November 04, 2009

Does this solve the licensing issue? Looking to ditch sIFR

Rain said on November 09, 2009

Nice work dude! Thanks a lot! :)

Tino said on November 10, 2009

This post changes everything in web design!
Thank you Snook!

With http://www.fontsquirrel.com/fontface/generator it's even easier to generate all files u need. Haven't found any bugs yet.

Thomas said on November 15, 2009

Thanks for this great article.

What I'm wondering is what to do with different font weights (normal and bold). Do I have to use to separate font-face definitions or is it possible having two different weights in one ttf/eot/svg?

David Levin said on November 17, 2009

I'm a first time visitor to your site but I was really captivated by your article. I totally thought that font-embedding was one of those CSS tricks I wasn't going to be able to implement for years to come. I'll have to test this out in my next project. Thanks for the introduction!

Shawn S said on November 17, 2009

Great article.

Question: If people have their IE security settings set fairly high, any page that has a @font-face embedded font will make IE pop up a warning dialog stating something along the lines that the page is trying to install something.

Clicking OK allows it to load the fonts on the page, but every page you visit continues to pop-up that warning.

Any suggestions on getting around this warning message (other than telling people to lower their settings)?

BTW: I've tested this on WinXP w/ IE6/7/8 - All give this warning.

Jonathan Snook said on November 17, 2009

@Shawn S: It's possible that a flag can be set in the EOT as far as what level of embedding is allowed. I have no idea whether this will solve the problem. Not sure if ttf2eot allows for setting the embedding flags.

Shawn S said on November 17, 2009

I used the EOT tool at http://www.fontembedding.com/eot/ but it doesn't have any additional options (other than specifying the domain to be used).

The example on webfontspecimen.com also displays the message.

I'll have to give TTF2EOT a try. Thanks for the response.

Sorry, comments are closed for this post. If you have any further questions or comments, feel free to send them to me directly.