Super Plugin Sale! Your Choice: BOGO or 30% Off »
Web Dev + WordPress + Security

Quick and Easy CSS @font-face Code

[ @font-face ] I’ve been using custom fonts in my designs for quite a few sites now, and have refined what seems to be an ideal chunk of CSS code for implementing the @font-face rules. Some of the sites that include these rules include Perishable Press and Digging into WordPress, which look more stylish and refined with the custom fonts in effect. I’ve tested this code on quite a few browsers, including the following:

  • Safari 3.1+
  • Opera 10+
  • Firefox 3.5+
  • Chrome 4.0+
  • Internet Explorer 6+

This technique delivers your custom fonts quite consistently to all of these browsers, and degrades gracefully for those that don’t support it. Of course, there are always weird exceptions contingent in particular scenarios, but overall it’s a solid chunk of code put together from much research, experimentation, and testing. I share it here hoping it will help others implement custom @font-face fonts quickly and easily. Let’s step to it..

Complete CSS @font-face code for embedding custom fonts

After uploading your set of custom font files to a “fonts” directory, add the following CSS code to your stylesheet, which itself should be located in the same directory as your fonts folder:

@font-face { /* declare fonts */
	font-family: "MuseoLight";
	src: url("fonts/Museo300-Regular.eot");
	src: local("Museo 300"), local("Museo-300"),
		url("fonts/Museo300-Regular.woff") format("woff"),
		url("fonts/Museo300-Regular.otf") format("opentype"),
		url("fonts/Museo300-Regular.svg#Museo-300") format("svg");
		/* display fonts */
		h1 { font: 24px/1 MuseoLight, Verdana, sans-serif; }
		h2 { font: 18px/1 MuseoLight, Verdana, sans-serif; }
		h3 { font: 14px/1 MuseoLight, Verdana, sans-serif; }

That’s the magic ticket. In the first ruleset, we are declaring which fonts to use for each of the four different formats. After this, the next three rulesets are used to actually display the fonts according to our desired property values. You can apply just about any CSS styles you wish, so long as the font-family (or simply “font” if you are using shorthand) contains the name of your custom font.

Notice that we declare the font-family as “MuseoLight” in the first declaration block of the first ruleset. Then we also specify MuseoLight as the name of our first font for each of our heading selectors (h1, h2, and h3). After specifying our custom font, we then declare a couple of common system fonts – Verdana and sans-serif – to serve as fallbacks. In other words, this font-embedding technique degrades gracefully when the custom font is not displayed.

Update: check out the followup post on @font-face code for more information on proper usage.

For our custom font, we are using the beautiful Museo font by Jos Buivenga. You can embed just about any font you like1, so long as you include files for each of the following four formats:

  • .eot – e.g., Museo300-Regular.eot
  • .otf – e.g., Museo300-Regular.otf
  • .svg – e.g., Museo300-Regular.svg
  • .woff – e.g., Museo300-Regular.woff

There are many ways to obtain a good working set of fonts, but my favorite is Font Squirrel. They just make it so incredibly easy to download all of your favorite prepackaged @font-face kits. Just download, unzip, upload, and done!

Important notes

If for some reason your fonts aren’t displaying, here’s a few things to keep in mind:

  • Don’t nest different @ selectors!
  • Number one reason for failure is incorrect path names
  • Force-refreshing and/or emptying your browser cache may help
  • You may also want to append a query-string parameter to your CSS URL to force refresh the user’s browser

Also important to keep in mind is that font embedding is only possible because of the many talented people who freely share their ideas, knowledge, and discoveries with the open-source community. Thanks to them, we can all look forward a better font-embedding experience in the future.

Closing thoughts

Enhancing your design with some choice typography is a great way to beautify and personalize your website. Sure the CSS code looks rather grotesque, but it’s an effective solution for cross-browser font embedding. Just upload your four font files and slap in the code. It’s pretty simple, but feel free to ask any specific questions in the comments. I’m no font-embedding guru, but I’ve been designing with embedded fonts for quite awhile. As always, if you know of a way to improve on this code, speak up and share your wisdom!


  • 1 Assuming the font is licensed as to allow such use.

About the Author
Jeff Starr = Web Developer. Book Author. Secretly Important.
GA Pro: Add Google Analytics to WordPress like a pro.

23 responses to “Quick and Easy CSS @font-face Code”

  1. Marty Thornley 2010/04/13 6:18 pm

    Could you explain the line that says: ‘src: local(“Museo 300”), local(“Museo-300”),’ Followed by three urls with format declarations and why that is different from the one line with the .otf?

    It is not at all clear where those different lines came from or how that would translate to another font.

    Thanks for another great post, btw. Looking forward to trying this out, but really have no idea what is going on in those different lines.


  2. Jeff Starr 2010/04/13 7:11 pm

    Yeah, that’s a good point. I was trying to keep the article as simple as possible and not go into too much detail, but I see that more explanation of the code itself may be needed. I’ll either update the article or maybe even branch off into more of an “in-depth” post focusing entirely on the code and how to use it with it other fonts in a more general sense.

    Thanks for the feedback :)

  3. Marty Thornley 2010/04/13 7:25 pm

    Thanks, Jeff!

    Looking forward to it. :)

  4. Alex Denning 2010/04/14 12:46 am

    Font squirrel is pretty epic – it makes it just so easy to use @font-face and cross browser too; I’m rather at a loss why more people don’t use it!

  5. Derek Johnson 2010/04/14 7:56 am

    @Jeff I got this from

    You’ll notice there are two calls to local(); the first is for the full name, the second for the Postscript name; this is required for Safari in OS X.

    The full blog post is at

  6. Hey Jeff. Thanks for the overview. It will be great to use as browser support becomes more widely available. In the meantime I’m looking at Cufon which seems very interesting.

  7. Derek Johnson 2010/04/14 8:02 am

    Sorry, my last post should have been @Marty. I don’t think Jeff was lacking in that knowledge!

    @David, cufon is good, but only for headings. A bad idea for body text. Also, the list of browsers Jeff has tested this method in counts as widely available browser support in my book.

  8. @Marty: Here is a followup post with visual walkthrough of @font-face.

  9. Frank Martin 2010/04/15 3:11 am

    If you declare real names in local(‘example’) it will prompt the user if they don’t have the font on their system which will result in a lot of people clicking cancel instead.

    An easy fix is to use local(‘☺’), at they generate this code for you!

    Also Cufon puts in some nasty markup.. @font-face all the way.

  10. I love this and you happen to be using the font I need to use on my current designs.

    But why do you have to have the css file that is using @font-face in the same directory as the fonts? or is this just to make sure all the links in this example don’t break?

  11. Derek Johnson 2010/04/15 6:07 am

    You don’t. I use url(“../fonts/Museo300-Regular.woff”) format(“woff”) for example. You just need the relative path from the stylesheet to be correct.

  12. I’ll be sticking to Cufon for the foreseeable future, I cant handle how nasty @font-face looks in some browsers, when cufon is perfect in all of them. If I wanted custom body text (which nine times out of then, I don’t) then this would be handy.

    When its better supported and displayed in most browsers on most platforms however, @font-face will be a winner.

Comments are closed for this post. Something to add? Let me know.
Perishable Press is operated by Jeff Starr, a professional web developer and book author with two decades of experience. Here you will find posts about web development, WordPress, security, and more »
Digging Into WordPress: Take your WordPress skills to the next level.
All free plugins updated and ready for WordPress 6.6 dropping next week. Pro plugin updates in the works :)
99% of video thumbnail/previews are pure cringe. Goofy faces = Clickbait.
Crazy that we’re almost halfway thru 2024.
I live right next door to the absolute loudest car in town. And the owner loves to drive it.
8G Firewall now out of beta testing, ready for use on production sites.
It's all about that ad revenue baby.
Get news, updates, deals & tips via email.
Email kept private. Easy unsubscribe anytime.