Using CSS3 and @font-face to use any custom font on a web site

I should have written about this long ago, but better late than never – time to share my experiences. Typography is an important part of user experience, and with CSS3 @font-face we can offer users any font we want to.

CSS3 @font-face

Font-face works just like the @media directive, where you declare a font-face’s family name and the source of the font file(s) you want to use. Additionally you can also control the font’s weight and style. A very simple example looks like this:

@font-face {
	font-family: "ChantelliAntiquaRegular";
	src: local("☺"), url("Chantelli_Antiqua-webfont.ttf") format("truetype");
	font-weight: normal;
	font-style: normal;
}

The smiley character there is basically just a way to avoid referencing a local font on the machine/device and not ending up with what you hoped for. Paul Irish describes this in more detail in Bulletproof @font-face syntax.

Updated February 1st 2011

As Richard Fink points out in Best Practice For @Font-Face CSS Takes A Turn, there is a issue with using the smiley face, and an alternate method is the Mo’ Bulletproofer @Font-Face CSS Syntax with double declarations.

Then to use the font you just refer to it like any other font family, i.e.:

h1 {
	font-family: "ChantelliAntiquaRegular";
}

Various font formats

However, there’s a multitude of font formats to use, so let’s break down each of them:

TrueType (.ttf)

The most common font format on Windows and Mac. Considered a raw format, as it’s not optimized for the web.

OpenType (.otf)

Built based on TrueType, offering more capabilities. Also considered a raw format.

WOFF – Web Open Font Format (.woff)

WOFF is an open compressed version of TrueType/OpenType fonts, which also supports metadata inclusion separated from the font data. It is regarded as an optimal format for web font usage.

EOT – Embedded Open Type (.eot)

Designed by Microsoft to be used for fonts on web pages. Can be created from the TrueType font format.

SVG (Scalable Vector Graphics) Fonts (.svg)

Font rendering based on SVG. You can also use .svgz which is a gzipped version of SVG fonts.

Web browser support

Having shown basic usage of @font-face and having gone through various existing font formats, let’s look at web browser support.

@font-face

The support for the @font-face is quite widely implemented:

  • Internet Explorer 4+ (yes, for real)
  • Mozilla Firefox 3.5+
  • Google Chrome 4+
  • Safari 3.1+
  • Opera 10+

WOFF support

  • Internet Explorer 9+
  • Mozilla Firefox 3.6+
  • Google Chrome 6+
  • Safari 6+
  • Opera 11.1+

OpenType support

  • Mozilla Firefox 3.5+
  • Google Chrome 4+
  • Safari 3.1+
  • Opera 10+
  • iOS Mobile Safari 4.2+

TrueType support

  • Internet Explorer 9+ (although a bit unclear)
  • Mozilla Firefox 3.5+
  • Google Chrome 4+
  • Safari 3.1+
  • Opera 10+
  • iOS Mobile Safari 4.2+

EOT support

  • Internet Explorer 4+

SVG Fonts support

  • Google Chrome 4+
  • Safari 3.1+
  • Opera 10+
  • iOS Mobile Safari 3.2+

What this means in practice is that you need to support WOFF, TrueType (or OpenType), EOT and SVG fonts for your web page to reach as many as possible.

A real-world example of using @font-face

With various font formats supported across the board, this is how a real-world example could look like:

@font-face {
	font-family: "ChantelliAntiquaRegular";
	src: url("Chantelli_Antiqua-webfont.eot");
	src: local("☺"), url("Chantelli_Antiqua-webfont.woff") format("woff"), url("Chantelli_Antiqua-webfont.ttf") format("truetype"), url("Chantelli_Antiqua-webfont.svg#webfontZjhIjbDc") format("svg");
	font-weight: normal;
	font-style: normal;
}

Updated February 1st 2011

As mentioned above, an alternate approach is to use double declarations, shown below.

@font-face {
	/* This declaration targets Internet Explorer */
	font-family: "ChantelliAntiquaRegular";
	src: url("Chantelli_Antiqua-webfont.eot");
}

@font-face {
	/* This declaration targets everything else */
	font-family: "ChantelliAntiquaRegular";
	src: url(//:) format("no404"), url("Chantelli_Antiqua-webfont.woff") format("woff"), url("Chantelli_Antiqua-webfont.ttf") format("truetype"), url("Chantelli_Antiqua-webfont.svg#webfontMFqI76bT") format("svg");
	font-weight: normal;
	font-style: normal;
}

As you can see here, first we declare a reference for the .eot font file, to make sure it works in older versions of Internet Explorer. Then we have the bullet-proof approach of avoiding local font files and then specifying various font file references and their formats in consecutive order until the web browser finds a format it supports.

Naturally, this means that you will need to have many formats of the same font to be available to target as many end users as possible.

A demo

If you go to my CSS3 @font-face test page, which is part my CSS3 test suite, you can see this code in action and see how it is rendered in various web browsers.

Font Squirrel

An excellent resource both for finding open fonts, free to use, and to generate the above @font-face code and corresponding font files, is Font Squirrel. They have ready kits for download and also their @font-face generator – just upload a font file and get lots of formats and ready CSS code back.

Security and protected fonts

This is all fantastic, right? Now can offer any font to the end users of the web sites we build, and our customers can finally use their own font. Well… Since you refer directly to the font files and make them publicly available on your web server, that means anyone can download them. And, as an extension of that, they can install the fonts on their machines, use on their own web sites etc.

While that might not seem like a problem to you, it’s about rights and ownership for the font(s) in use, and it is something you are required to consider.

When using Font Squirrel’s @font-face generator, you have an option that the font should not be installable on any desktop machine, leaving it only working on other web sites. Some customers will be cool with that. However, if you are using a bought font from a font foundry, chances are that you will not be allowed to have that available on your web server (same goes for some companies’ custom fonts).

In that case, Typekit could be an option for you, where they store all the fonts and they will only be accessible from your web site and completely protected. You can look at their pricing and see if it’s interesting.

Therefore, in the end, you need to take each case into consideration and do what’s right. My completely personal view would be:

  1. Choose an open font or find an open font that looks close enough to what you want.
  2. Use the customer’s font and ask them if it’s ok as long as it’s not possible for anyone else to install it on their machines.
  3. Look at Typekit and see if they can offer what you need.

Now, go use some amazing fonts!

23 Comments

  • […] This post was mentioned on Twitter by Robert Nyman, Palle Zingmark, Gavin Taylor, Ludvig Lindblom, ????????? ???????? and others. ????????? ???????? said: ?????????? ???? ?????? ?? ????? ? ??????? #CSS3 ? @font-face http://goo.gl/Zycv8 […]

  • Thanks Robert, there has been a lot written about using @font-face but not many posts are as clear and succinct as yours.

    For me one very important part of using fonts with @font-face is to thoroughly check the rendering on different platforms and in different browsers. The lack of good anti-aliasing and poor hinting across the board can mean fonts look awful if you don’t choose carefully.

    Thanks again 🙂

  • Robert Nyman says:

    Darren,

    Thank you, that makes me very happy to hear! 🙂
    And yes, testing/evaluating font rendering across the board is also very important!

  • fvsch says:

    Small coincidence, the @font-face test page I did back in 2009 used the same font, Chantelli Antiqua.

    Anyway, the number one feedback I get from designers and front-end developers working on web agencies, building websites for “regular” people on (mostly) Windows is that the rendering is most of the time too bad to inflict on end users. This is the one big issue remaining, now that commercial font licensing and the WOFF format are picking up steam.

    We’ll probably have to wait for the demise of Windows XP (end of support is in 2014) and the optimization of fonts for rendering on Windows 7 (still problematic with some fonts), plus the correction of tangential rendering bugs in browsers, for @font-face to become a simple solution. We’re not there yet.

  • Robert Nyman says:

    fvsch,

    Ha ha, great coincidence! Even funnier considering I had another font first, and changed my mind the last second. 🙂

    But you are absolutely right: font rendering in Windows is usually terrible, although better in Windows 7. At the same time, though, what we usually miss in that argument is that every font usually looks bad in Windows, not just the one we have chosen – point is, Windows users are generally not as spoiled with good font rendering.

    But yes, at the end of the day, we do need to do testing and evaluation to weigh the pros and cons against each other.

  • Steve Williams says:

    Great article! I used Typekit on a project early in 2010, found it easy to setup and it worked well for the course certificate template editor I was building that required a typical Gothic typeface. So much so, I tried Typekit on my own site for headings and blockquotes.

    I found similar issues with Windows rendering, italics were very jagged unless large and typefaces varied as to how readable they were at any given size, so testing across platforms is important 🙂

  • Robert Nyman says:

    Steve,

    Thank you!
    Yes, always the Windows rendering coming creeping…

  • fritz says:

    Hi. Nice post, and good of you to remind developers of their obligations with regards to distribution – something that a lot of other similar posts fail to mention.

  • Bala says:

    Thanks for the great tips!

  • Robert Nyman says:

    Fritz, Bala,

    Thanks, glad you like it!

  • Richard Fink says:

    Robert,

    There are serious problems with the “smiley face” @font-face syntax you are suggesting. It will not work on Android, for example, due to a bug.
    Both Font Squirrel and the free font service Kernest have stopped offering it as the default.
    See here:
    http://readableweb.com/best-practice-for-font-face-css-takes-a-turn/
    and here:
    http://readableweb.com/mo-bulletproofer-font-face-css-syntax/

    For a more robust solution.

    Regards,

    Rich

  • Robert Nyman says:

    Richard,

    Thanks for the input!
    I have now updated the blog post.

  • Hi Robert, best practice for @font-face declaration has changed yet again within the space of a week!

    See the method suggested by Fontspring here:
    http://www.fontspring.com/blog/the-new-bulletproof-font-face-syntax

    This improves on the Mo’ Bulletproofer method.

  • Robert Nyman says:

    Darren,

    Thanks for the update!
    That is indeed quite interesting. However, with not complete security about IE9 yet and that this new approach needs more testing and usage, while the Mo’ Bulletproofer is work for sure, I think I’d recommend that for now.

    But for sure, this is interesting development and I hope it will work out!

  • Ailin Hernández says:

    Thank you!! very helpful 🙂 Cheers from México!!

  • Robert Nyman says:

    Ailin,

    Glad you liked it!

  • Intumesco says:

    I still cant make it work while i tried almost every method on google including this one. Or am i just making some small mistake ? In google chrome and firefox it works well. But in ie8 and ie9 it just wont work. (hate internet explorer..) here is my code:

    @font-face {
    font-family: ‘MyriadPro’;
    src: url(‘myriadpro-webfont.eot’) format(‘eot’),
    url(‘myriadpro-webfont.woff’) format(‘woff’),
    url(‘myriadpro-webfont.ttf’) format(‘truetype’);
    }

    //scrolled down to the first button of the navigation menu

    .home
    {
    font-family:MyriadPro;
    font-size:30px;
    position:relative;
    z-index:2;
    bottom:37px;
    left:60px;
    }

    .home a:link, .home a:visited
    {
    font-family: MyriadPro;
    font-size: 30px;
    color: #FFFFFF;
    text-decoration: none;
    }

    .home a:hover
    {
    font-family:MyriadPro;
    color:#21BEDE;
    text-decoration:none;
    }

    And this works fine in chrome and in firefox..
    I hope someone can help me out here. And believe me iv done a lot search and type work for this. Still couldn’t fix it =[

  • Robert Nyman says:

    Intumesco,

    There are two errors in your code:

    First, there’s no semicolon after the .eot file inclusion.
    Second, you will need two src attributes.

    Please copy the code from this post or the demo page and it will work.

  • Intumesco says:

    it worked! thanks a lot !

  • Robert Nyman says:

    Intumesco,

    Great!

  • Okay, so I’m using the bulletproof smiley syntax and while I understand how it works I can get it to work in EVERY browser except IE browsers.

    Can someone check my style sheet here and tell me if I’m doing something wrong?

    http://www.1stchoicerecyclinghvac.com/css/style.css

    Oh, and here is the website in question… http://www.1stchoicerecyclinghvac.com

    The site is by no means done but if you’re using IE you will see the fonts don’t show up at all and I can’t figure out for the life of me why.

  • Robert Nyman says:

    Chris,

    The EOT files should not be listed with the smiley syntax, only before it. Maybe that helps.

  • […] sokat írtak a saját fontok használatáról, ez egy lényegre tör? összefoglaló, minden fontos benne van, mégsem b?beszéd?. […]

Leave a Reply to Darren Armstrong Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.