Making Sites Shine with @font-face

Emily P. Lewis | January 5, 2011


Like many of my web designer brethren, I’m a bit of a typographic geek. And like many web designers, I’ve been frustrated (to say the least) about the historical state of web typography.

At first, we were limited to a common, but very small set of “web safe” fonts. Anything beyond those fonts, we had to rely on images. Images for text not only meant we had to create and maintain dozens (if not hundreds) of images, but it introduced accessibility issues.

Over time, some clever image replacement techniques evolved to address those accessibility challenges, but we still had the overhead of image creation on top of HTML/CSS development. Flash techniques like sIFR and Cufón reduce the overhead, but they could be unreliable, the font rendering inconsistent and, of course, they needed Flash (and/or JavaScript) support.

Hello! My Name Is @font-face

During the same time people were struggling with font alternatives, the CSS 2 specification introduced @font-face as a way to link to actual font files via CSS:

@font-face {
    font-family: "ChunkFiveRegular";
src: url('Chunkfive-webfont.ttf') format("truetype");

And then utilize those specified fonts in style declarations:

h1 {
    font-family: "ChunkFiveRegular", serif;}

And everyone rejoiced, right? Wrong.

The specification was where designers wanted to go, but browser support for the most widely used format, TrueType, didn’t exist. And then each browser vendor decided to support different, rarely-used formats. Plus, there were the licensing issues. Even if you had supported font formats, that didn’t mean you could legally use those fonts with @font-face.

But now, over a decade later, the landscape for web fonts is far more open and surprisingly easy to navigate. Let’s navigate it, shall we?

Browser Support Today

One of the major differences in the use of web fonts today, versus back in 1998 when @font-face was introduced, is browser support.

All of the latest browsers support @font-face and many more file formats are supported, including the TrueType/OpenType TT (.ttf) and OpenType PS (.otf) formats. Unfortunately, “latest” doesn’t include Internet Explorer before version 9.

From the very beginning of @font-face, IE had only supported its proprietary Embedded OpenType (.eot) format, which helps restrict the use of copyrighted fonts. With IE 9, though, you get full TTF and OTF support, as well as WOFF and SVG.

Meanwhile, Chrome and Firefox also support WOFF, while SafariMobile and Opera support SVG. It sounds more complicated than it is:

  .ttf .otf .woff .svg .eot
Chrome v4+ v4+ v6+    
Firefox v3.5+ v3.5+ v3.6+    
Internet Explorer V9   v9 v9 v4+
Opera v10+ v10+   v10+  
Safari v3.1+ v3.1+   SafariMobile iOS 4.1+  

With this much improved browser support and a variety of formats, @font-face has become a regular part of my design repertoire. Not only does it satisfy my inner typographic geek, but also I save time not using image replacement techniques and simply relying on a @font-face rule.

First, Get a Font

Before you can dive into the wonderful world of @font-face, you first need to choose a font. And not just any font, but a font that is licensed for web use. You don’t want to violate any EULAs or copyrights, do you?

There are many free and commercial fonts that have web licenses, making it easy for you. These are the top sites I visit when looking for a properly licensed font:

Who’s the Host?

Some fonts, you can download and host yourself, others you can only use hosted versions. If you already have a font that is licensed for web use, for example, you can save it to your web server and reference those files in your CSS. But you do need to take several things into consideration.


If you host your own fonts, you will need to have several formats to ensure cross-browser support. Minimally, that means an .eot for IE and either .ttf or .otf for the other browsers.

There are a few font conversion services you can use to make sure you have all the formats:

Before using these, I recommend you watch Jonathan Snook’s screencast on converting fonts. And double-check your font license to ensure conversion to other formats is allowed.

Also, be aware of file sizes and your ability to serve those files efficiently. Font files aren’t small, and can affect page performance. You can, though, gzip your @font-face files to help with optimization, and try lazy loading to help IE performance.


At this point, you may be wondering if @font-face is even worth it. You have to find the font, convert it, optimize it … and that’s before you even address the actual @font-face CSS.

Fortunately, there is a great service that does all of this (and more) for you: FontSquirrel.  Looking for free fonts? FontSquirrel has an impressive selection:

Looking for free fonts with web licenses? Filter your search on @font-face licensing, as well as file format and typographic style:

Once you’ve selected your font, you just download it with a single click. But then you would have to worry about the conversion. FontSquirrel has you covered with its @font-face generator, which not only converts your font to the appropriate formats, it generates the CSS for your @font-face declarations. A few clicks, and you have a custom “@font-face kit”:

Choose the one-step “Easy” route or get fine control over the conversion:

And just when you thought it couldn’t get any easier, FontSquirrel has pre-made kits you can download:

If you can’t tell already, I really like FontSquirrel. It makes using @font-face, particularly for your own hosted fonts, so easy you can’t help but want to try it.


Some fonts, however, aren’t available for self-hosting due to licensing restrictions. Or maybe you have concerns about hosting yourself. Fortunately there are many hosted options:

Both TypeKit and FontDeck let you “rent” their hosted @font-face fonts. You pay an amount (they each have totally different models), and then you get the code needed to use their fonts.

For example, I purchased an annual license from FontDeck for the use of Mahalia on my web site. In return, FontDeck gives me the CSS and markup I need to add to my site:

The benefit of these services is they offer many fonts you can’t otherwise use with @font-face, such as the Adobe fonts featured on TypeKit. Plus, they host the fonts, which are optimized (and maintained) for file size and browser support. But these benefits come with a price.

If you aren’t interested in laying down cash for your @font-face endeavors, but you do want the optimization, speed and delivery benefits of CDN-hosted, Google offers several free and hosted fonts. Just pick your font, and they give you the CSS:

Second, Implement @font-face

As you can see there are so many different ways for you to choose your fonts. Once you’ve decided, it is a simple matter of adding the necessary CSS. And, remember, if you are using a hosted font, you don’t even have to write it yourself.

Let’s take a close look at what FontDeck gave me for my Mahalia license:

<link rel="stylesheet" href="" type="text/css" />

As you can see, this is just like any external CSS file (and, yes, that means another http request). It contains the @font-face rules needed to display Mahalia on my site and accounts for all file formats:

@font-face {
    font-family: 'Mahalia Regular';
    src: url('…xs.eot');     
    src: local('Mahalia Regular'), url('…xs.woff') format('woff'), url('…xs.ttf') format('opentype'),     url('…xs.svg#630') format('svg');     
    font-weight: normal;     
    font-style: normal;

Then I can assign the “Mahalia Regular” font to whichever content I want:

aside h2 {
font-family: 26px "Mahalia Regular", "Lucida Handwriting", cursive; 
font-size-adjust: 0.438;
font-style: normal;
font-weight: normal;
text-shadow: 1px 1px 3px #666;

And, viola, I have a lovely script font enhancing my site quite nicely (if I do say so myself):

Picking a Method

There are a handful of different methods for @font-face rules. For example, the method FontDeck uses may not be the same as TypeKit’s or Google’s. But when you are using these hosted fonts, you don’t really have to think about it because they give you what they recommend and are maintaining.

If you are self-hosting, though, you should carefully decide which implementation you prefer:

For my own self-hosted fonts, I’ve become fond of Paul Irish’s bulletproof smiley method:

@font-face {
font-family: 'ChunkFiveRegular'; 
src: url('Chunkfive-webfont.eot'); 
src: local('☺'), url('Chunkfive-webfont.woff') format('woff'), url('Chunkfive-webfont.ttf') format('truetype'), url('Chunkfive-webfont.svg#webfont4CzPTNtF') format('svg'); 
font-weight: normal;
font-style: normal;

This ☺ method accounts for a variety of issues and inconsistencies, and every time I use it I’m thankful he took the time to test and document, because it makes my life a breeze.

Don't Forget Fallback Fonts

Fallback fonts are nothing new. It’s the concept of specifying several fonts as the font-familyvalue, so if a browser doesn’t support the first font in the list, it moves on to the next listed and so on. Because not everyone has the latest browsers and not everyone enables web fonts in their browsers, you should still specify a fallback font stack when using @font-face.

Notice in my example above, I include a relatively “safe” web font, as well as a generic:

font-family: 26px "Mahalia Regular", "Lucida Handwriting", cursive;

While it is only supported in Firefox, you can also add font-size-adjust to your rule to account for different aspect ratios for the fonts in the stack, like I did for my Mahalia rule:

font-size-adjust: 0.438;

Weight & Style

The examples I’ve shown so far are for the roman versions of typefaces. That’s why you see the font-weight: normal and font-style: normal declarations included in the rules. If I wanted to have bold or italic, it is, unfortunately, not simply a matter of indicating font-weight: bold or font-style: italic.

Even though these are, technically, styles of a typeface, they are actually different fonts which have to be independently declared. For my personal site, I license Calibri, which references four different fonts to account for the four styles (roman, bold, italic and bold italic):

@font-face {
font-family: "Calibri";
src: local("Calibri"), url("…835") format("truetype");
font-style: normal;
font-weight: normal;

@font-face {
font-family: "Calibri Bold";
    src: local("Calibri Bold"), url("…1dc") format("truetype");
    font-style: normal;
    font-weight: bold;

@font-face {
font-family: "Calibri Italic";
    src: local("Calibri Italic"),  url("…40f") format("truetype");
font-style: italic;
    font-weight: normal;

@font-face {
font-family: "Calibri Bold Italic";
    src: local("Calibri Bold Italic"),  url("…0a4") format("truetype");
font-style: italic;
font-weight: bold;

Third, Realize Nothing’s Perfect

While the new possibilities with @font-face offer what I believe is a better world for fonts on the web, it has its issues:

  • Font files can be large and slow performance. This, in turn, can cause a Flash of Unstyled Text (FOUT).
  • Each font used for @font-face is another http request, so be thoughtful and don’t overuse.
  • Not all browsers support @font-face, which is why the font stack comes in handy. You can also explore JavaScript solutions that detect support, such as Modernizr and Font Face Detect.
  • Font rendering varies not only from browser to browser, but also OS. This isn’t an issue with @font-face per se, but worth mentioning if you haven’t yet experienced the disappointment of viewing your pretty fonts on a platform that doesn’t do anti-aliasing well.

Lastly, Start Experimenting

In addition to the excellent services and tutorials I’ve already mentioned, the following resources are must-reads if you want to explore @font-face further:

And don’t forget, it isn’t all about the technical implementation. Design, style, flow and rhythm are essential for beautiful web design:

Look for inspiration, because so much is possible today and it only looks to get better:


About the Author

Emily Lewis is a freelance web designer of the standardista variety, which means she gets geeky about things like semantic markup andCSS, usability and accessibility. As part of her ongoing quest to spread the good word about standards, she writes about web design on her blog, A Blog Not Limited, and is the author of Microformats Made Simple and a contributing author for the HTML5 Cookbook. She’s also a guest writer for Web Standards magazine and MIX Online.

In addition to loving all things web, Emily is passionate about community building and knowledge sharing. She co-founded and co-manages Webuquerque, the New Mexico Adobe User Group for Web Professionals, and is a co-host of the The ExpressionEngine Podcast. Emily also speaks at conferences and events all over the country, including SXSW, MIX, In Control, Voices That Matter, New Mexico Technology Council, InterLab and the University of New Mexico.

Find Emily on: