A million ways to embed custom fonts (and keep typography nerds off your back)

custom font embedding

It’s happened more times than I can remember: I finish a front-end for a site, using custom font embedding, pixel-for-pixel CSS, the works. But when it comes time for design review, the designer moans: “Can you make that font a bit heavier, it doesn’t look organic!” Assuming that “organic” really means something and ignoring that the font looks 99% identical to Helvetica, I have to trust their better judgement.

Has this happened to you? Well it’s time for us developers to stop complaining about web typography. Custom font embedding has been around for years, and it has finally gotten to the point that typography nerds can be equally happy with the fonts on a website as they are with the Photoshop comps. Many of the things that were a total pain to support previously have become a piece of cake. Leading, kerning, and all the major typography buzzwords have been handled for some time. Even drop shadows and Photoshop-style font rasterization options such as ‘strong’ and ‘crisp’ are now fully supportable.

So let’s make sure that we don’t become dinosaur developers, and get up on these modern methods of custom font embedding.

In this article we’ll cover all types of font embedding, from older image replacement methods to embedding fonts with Flash, as well as native browser methods and even full Javascript font support with the new script Typeface.js.

Dynamic image replacement (The old way)


In order to fully appreciate how far custom font embedding has come, it is important to learn a bit about its history. However if you really don’t care, feel free to skip to the next section, since these methods are all but obsolete.

A few years ago the primary way to embed non-web-safe fonts on a website was more complex. Basically, the backend would use a graphic script like ImageMagick to convert a font file into an image for phrases on the fly. At the browser level, Javascript would then replace that phrase in the HTML with the image. See an example here.

The main drawback to this method of custom font embedding is that it’s very resource heavy. While the importance of caching for these early scripts is obvious, even then it only made sense to replace a few headings here and there, and totally dynamic content could present a processing problem.

Additionally, once the Javascript kicked in and replaced the given text, the user would see the change flicker in their browser, a problem amplified by slower computers. Finally, since this method would essentially take the font and slice it up into a series of images, only the very basic aspects of the font were supported. If, for instance, you wanted to use bolding, the script would have to use a new font file, an additional cache for those phrases, etc.

The Verdict:
PHP and backend font embedding is obsolete; use the more modern methods below.

Enter sIFR 2 and Flash embedding

sIFR 2

While the original methods of custom font support are fairly obsolete, they did pave the way for more modern methods, one of which is Flash based embedding. Fully supportable on regular HTML pages, Flash embedding draws on a lot of the same concepts as image replacement scripts: custom font areas are flagged within the HTML and Javascript is used to replace the original websafe text with the custom font. The only difference is with Flash embedding, Flash is used for the font support, rather than a backend ImageMagick script.

Supporting custom fonts using Flash makes sense for a variety of reasons. Flash natively supports custom fonts, which are embedded within the SWF file. Since the SWF is compiled, the font is furthermore inaccessible to end users, thus eliminating any licensing concerns. Also, since the Flash replacement occurs entirely on the front-end, it can be achieved without backend access and more importantly without a large toll on the server. For all these reasons, I switched immediately to Flash font support with sIFR 2.

sIFR 2 supports a variety of typography options beyond simply embedding the font. Italics, bolding and underlining can all be achieved with a single file. Beyond these there are controls for letter spacing (kerning), line-height (leading) and other common typography requests. Additionally, sIFR 2 uses CSS 3 selectors to streamline the flagging of replacement text.

While sIFR 2 is a big step up from dynamic image replacement, it also has a variety of drawbacks. The main problem with sIFR 2 is that fonts tend to expand to fit the area of the SWF, which is determined by the dimensions of the original HTML text. For most developers this doesn’t present a huge problem, since font sizes are fairly easy to hack into place using line-height and other CSS tricks for the HTML text. However, for doing pixel perfect renditions of designer comps sIFR 2 is a total nightmare. I’ve pulled my hair out time and again with sIFR 2, with designers never seeming 100% happy with the end result.

The Verdict:
sIFR 2 is a pretty decent option, but sIFR 3 is better.

sIFR 3 solves sIFR 2’s bugs and more

sIFR 3

Thankfully, almost all my font replacement woes were resolved with the release of sIFR 3. While still officially in beta, sIFR 3’s advancements over sIFR 2 can not be ignored, and after extensive testing I am now using it in production.

Most importantly, sIFR 3 fixes the font-expansion issue described above, rendering font sizes with either a user-generated Javascript variable or the native font size of the HTML text by default. Like sIFR 2, sIFR 3 easily supports a variety of typography options. Additionally, sIFR 3 has made the styling of custom embedded fonts much easier, using more intuitive CSS controls and selectors.

Finally, sIFR 3 introduces a wider variety of styling options, offering drop shadows, outerglow and gradients on embedded text. See the sIFR docs for more info

The main drawback to sIFR 3 is that it still relies on replacing fonts using Javascript. Although it has methods to ensure that the user doesn’t see the change as a flicker, the user must still wait for the page to load, and then wait for the custom fonts. Furthermore, sIFR 3 requires Flash Player 8 or higher, however this is a non-issue for the vast majority of users. Finally, since the font is still being replaced dynamically, sIFR 3 is a bit cumbersome to use for all the fonts on a page.

I have encountered a few minor bugs with sIFR 3, mostly surrounding the wrapping of text in floated content, however I assume these will be cleared up with the full release.

The Verdict:
All things considered sIFR 3 is my favorite method for embedding custom fonts: feature-rich and well supported, it is currently the most headache-free option.

The new kid on the block: Typeface.js


Typeface.js is an interesting new script that embeds custom fonts using nothing other than Javascript. It provides a number of typography customization options, covering most of the basics such as font-weight, color and line-height in addition to offering some advanced typography options like font-stretch and letter-spacing.

While not the most feature-rich method, Typeface.js has the advantage of not requiring Flash Player to run. In addition, preparing fonts for use with Typeface.js is easier than with sIFR: instead of building a font file in Flash, fonts can be converted using either an online tool or a Perl module.

Typeface.js is still in its infancy and is unfortunately unusable in my opinion. While officially supporting all modern browsers, cross-browser implementation is spotty, with fonts rendering differently across different browsers. Additionally, it takes a long time to load in IE, and fonts are only selectable in browsers that support canvas.

Finally, the biggest drawback to embedding fonts with Typeface.js is licensing. While Flash embedding methods compile font files into the SWF, Typeface.js still exposes the font file to the end user. And as the Typeface.js website warns, “Many font vendors specifically prohibit redistribution and embedding of their fonts.” So make sure you have proper licensing before you use a font with Typeface.js.

The Verdict:
Typeface.js is an interesting project although not yet ready for use in production. In the future it may become a viable option for font embedding, however only with redistributable fonts.

And why don’t we just do it this way? (Native browser methods)

browser embedding

With the variety of methods for embedding custom fonts, it’s easy to forget that it shouldn’t be all that difficult. Why can’t we just pass the font file to the browser, and then allow it to render the page accordingly? Well it turns out in a lot of cases you can.

Custom font embedding has been supported by native browser methods since IE 4. Here Microsoft came up with Embedded Open Type (EOT), a proprietary file type that got around font licensing issues. To encourage EOT use, Microsoft also released a conversion tool: WEFT.

Embedding fonts through native browser methods is such a good idea that it was written into the CSS2 specifications by the W3C and is already being supported by Safari as well as betas for Firefox and Opera. However the EOT format is owned by Microsoft.

How to use it:
In browsers that support the font-face property, custom fonts can be embedded with a small chunk of CSS:

@font-face {
    font-family: "Robson Celtic";
    src: url("http://site/fonts/rob-celt")

Afterwards the font can be used as normal within the CSS:

p { 
    font-family: "Robson Celtic";
    font-size: 1em;

Isn’t that awesome? I mean no Javascript, no Flash, nothing but straightup markup. It’s really the way it should be, but unfortuantely we don’t live in a perfect world.

The main drawback to this method is cross-browser support. While supported by all modern IEs as well as Safari, current releases of Firefox and Opera are left out.

Additionally, since the proprietary EOT format only works in IE, different font files need to be passed to IE and the other browsers. Finally, with non-IE browsers developers run into the same licensing issues as with Typeface.js, where the font is exposed to the end user so only appropriately licensed fonts can be used.

The Verdict:
I really wish this were a viable option, however with the lack of current browser support, these native methods seem a long way off. Additionally, a new open-source or more freely distributed font format than EOT will need to be supported before developers can use browser-based methods for all fonts regardless of license.

So stick with sIFR 3 for now, it is currently the best method for embedding custom fonts.

Jon Raasch

Jon Raasch is a UX nerd and free-lance web designer / developer who loves jQuery, Javascript & CSS.

You Might Also Like:

29 Comments to “A million ways to embed custom fonts (and keep typography nerds off your back)”

  1. Graham Smith says:

    What a brilliantly informative post. Pretty much answered any questions and/or doubts I had about using font replacement for my own site.

    Good to see some of this info in one place, so often here there and everywhere.

  2. Matthias says:

    Great roundup, Jon. Thanks!

  3. temoc says:

    i think you missed some other options like cuf??n, maybe you can update your post, anyway a illustrative post, thanks.

  4. Jon Raasch says:

    Hi temoc,

    Good point! I’m planning on adding Cufon to this post just as soon as I have a chance to try it out, however I assume a lot of what I said regarding Typeface.js also applies to Cufon.

    Thanks for reading,

  5. I agree about cuf??n – I tried it successfully (all on Windows browsers) with Safari 3, Chrome, Firefox 3, and EVEN IE 6! Plus, these all worked with jQuery, too.

  6. rajesh katkam says:

    hello Jon Raasch,

    We are using @font-face to load TTFs dynamically for safari 3.x.
    Its working good if text not applied with bold and italic.

    Test Label1qesf dgdsfgdfgsdfgdsfgdfgdf

    the above HTML shows text in font-family bernie, but , tags are not affecting (The same HTML working fine in IE with EOT font files).


  7. rajesh katkam says:

    hello Jon Raasch,

    Sorry, this comment area not rendering HTML as it is.

    What i mean is the text “Test Label1qesf dgdsfgdfgsdfgdsfgdfgdf” contains strong and em tags with span tag contains style “font-family = bernie”.

    font-family applied to the text in my page, but strong and em tags are not applied in safari.


  8. Jon Raasch says:

    Thanks for posting that Rajesh, that’s great info!

  9. brainlag says:

    “Since the SWF is compiled, the font is furthermore inaccessible to end users, thus eliminating any licensing concerns.”

    This is not true. Everyone can decompile flash and even whenn only 10% of your users can doesn’t solve it your licensing problems.

  10. Jon Raasch says:

    Hey brainlag,

    I’m 99% sure that compiling a font into a swf covers you legally. Also 10% of users being able to decompile Flash seems like a pretty large exaggeration, unless we’re talking about some site that provides a Flash decompiler :-).

    Bottom line is that you really only need to make reasonable efforts to protect the licensing. Let’s say for instance that you run a print ad with a licensed font. Someone could scan the ad, pull apart the letters and recreate the font. There’s no such thing as perfect security, but as developers we have a responsibility to take reasonable measures in the interest of protecting any licenses we use.


  11. Musta says:

    This is really a very important tip especially for those who love using unusual fonts in their web designs.

    Thanks a lot for the article.

  12. David says:

    does anyone here know how to easily do this in RapidWeaver? I’d like to use font Dakta handwriting, in Safari it works, but in IE and Mozilla it reverts to a “web safe” font.

    Thank you,

  13. Kelly Johnson says:

    Good stuff. I’m guessing people are thinking of replacing more than just header copy for this.. otherwise, a basic image replacement technique (text-indent:-9000) is just as bullet-proof and in this day and age, the small graphics needed are nothing on the bandwidth.

  14. Recla says:

    Ok, I’m VERY new to web design. I love the solution at the end. But (and here’s where my ignorance shines through) how do I get my particular font loaded to the site/fonts?

    Details: I downloaded a font from dafonts and the creator allows for reuse. No licensing issue. I’ve created a web site using Front Page (still learning code, etc.) and then remembered the font was custom and didn’t show anywhere but my computer. I want an “easy” fix and don’t want to create a bunch of images. Please help! 🙂

  15. Geraldo Andrade says:

    Hey, dude. Checkout here: https://developer.mozilla.org/en/css/@font-face

  16. Great post but there now exists much better alternative that is Google Font API where you can use any font on your site from the Google’s font directory 🙂

  17. El Sonny says:

    I think with the adoption of @font-face by Opera and Firefox its preety much safe to use now. Welcome to the future.

  18. Steve Burrows says:

    I have been using the @font-face kit from Font Squirrel as a cross-browser solution with great success for some time now: http://www.fontsquirrel.com/fontface

  19. Adam says:

    Great article. Especially useful with php. The ability to skirt the vanilla list of common fonts is important in design. Now designers can use typography in a way that’s not relegated to images.

  20. I agree about cuf??n – I tried it successfully (all on Windows browsers) with Safari 3, Chrome, Firefox 3, and EVEN IE 6! Plus, these all worked with jQuery, too.

  21. Chelsea says:

    I’ve embedded the font-face for my custom font into my blog and it appears correctly when you go to the blog home page, but if you go directly to a certain post the font doesn’t appear. Can you direct me to a resource where I can figure out how to fix this?

    Thanks!!! This post was super helpful!

  22. Federomano says:

    As Steve said, get into http://www.fontsquirrel.com/fontface/generator and see the real thing working and painless.

  23. Zoltan says:

    Dear readers,

    Anyone please can help me on how to write web text to a curve/path?
    Part of the question is peretty much solved by this wonderful post. But I need to write onto a path ( a simple arc, not bezier or similar)

    Thanks, Zoltan

  24. Howdy would you mind letting me know which hosting company
    you’re working with? I’ve loaded your blog in 3 different browsers and I must say this blog
    loads a lot faster then most. Can you recommend a good web hosting
    provider at a reasonable price? Thanks, I appreciate it!

  25. Richard says:

    I use the @font-face extensively throughout my photo site. It works well in modern (post IE6) browsers.



  26. john Stokes says:

    Great post for usage using pc, mac and laptop….but iphone and ipad don’t support flash so you wont see font!

  27. Craft says:

    Dude, great article. Can you update this post or write a new one that thinks of CSS3 as well?


Comments are closed.