Celebrating 20 years online :)
Web Dev + WordPress + Security

Visual Walkthrough of @font-face CSS Code

[ @font-face ] In my previous post on Quick and Easy CSS @font-face Code, I provide a choice set of CSS rules for embedding custom fonts into your web pages. It’s a solid, cross-browser technique that works great, but as Marty Thornley pointed out, it would be useful to have a more thorough explanation of how the code actually works. So, rather than going back and adding a bunch of additional information to the original post, I’m following up with a visual walkthrough of the @font-face code.

In step-by-step visual format, this article will show you what the code is doing and how to use it with your own custom fonts.

Step 1: Declaring the @font-face rules

The first thing we want to do is copy & paste the quick and easy @font-face code into our stylesheet:

@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");

Yes, it’s a hideous-looking chunk of CSS, but that’s not going to stop us from using it to embed our own custom fonts. Let’s break it down and see how the different parts fit together..

[ Choose a unique font name to use in your stylesheet ]

First specify a name for your custom font. It can be anything, but keeping it logical and unique will make things much easier. This will serve as the name that you declare elsewhere in your stylesheet when applying the custom font to your chosen selector(s).

[ Specify the font's full name and PostScript name ]

In this line, we specify both the actual full name of the font and its PostScript name. This enables the browser to render your fonts using a local copy instead of having to download it from the server.

[ Use the actual file names for each of your four font formats ]

Here we are specifying the URL of each of the four different font formats. The first line targets Internet Explorer, while the other three lines target other types of supportive browsers.

[ Ensure the format matches the file type for the last three 'url' declarations ]

For these three format declarations, we want to make sure that they are matching up with their respective file types.

[ Specify the ID used during the SVG conversion ]

This fragment identifier refers to the font-specific ID used when converting the font to SVG format. If you converted the file yourself, then use whatever ID you specified, otherwise just open the font and look for the following code: <font id="Museo-300">. Of course, the ID will vary according to your specific font.

[ Double-check your file paths! ]

Just a friendly neighborhood reminder to double-check the accuracy of your file paths. This is probably the number reason why @font-face font-embedding fails to work.

Once you have the @font-face rules properly configured and your fonts uploaded, you’re essentially done with all of the “new” stuff. Everything from this point on is just business as usual. Our custom font is ready and available for use in our stylesheet just like any other commonly used font (such as Verdana, Arial, et al). So now let’s see how to apply our font to our chosen CSS selectors..

Displaying your custom font on the web page

Now that we have our custom font ready to use, displaying it in our design is as easy as including a font-family declaration to the desired selectors. To visualize how to do this, let’s add a few more lines to our current CSS code:

@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; }

For this walkthrough, we’ll apply our custom font to the top three heading elements, h1, h2, and h3. Note that we are using CSS shorthand notation to combine three properties – font-family, font-size, and line-height – into a single declaration block.

This is where it gets easy ;)

[ Use any selector supporting the font-family property ]

Here we are selecting the top three heading elements. They recognize the font-family property (or font when using the shorthand technique), so we’re good to go for applying our custom fonts.

[ Specify the same font name as used in the first line of the @font-face ruleset ]

Within each selector, include your font’s unique name in the font property value. Make sure it’s the first name in the list, followed by your preferred fallback fonts.

[ Declare suitable fallback fonts for when '@font-face' isn't supported ]

After declaring your primary font, throw in some fallbacks. If the browser doesn’t support @font-face, it will display the first available fallback font. Graceful degradation is a beautiful thing.

At this point, you should have a good understanding of how to specify your own custom fonts using @font-face. Once you have the actual font files, you have everything needed to configure your @font-face rules.

Now get out there and bring sexy back.

About the Author
Jeff Starr = Designer. Developer. Producer. Writer. Editor. Etc.
GA Pro: Add Google Analytics to WordPress like a pro.

18 responses to “Visual Walkthrough of @font-face CSS Code”

  1. Marty Thornley 2010/04/14 2:30 pm


    This is great! Thanks. As much as I know about CSS, this @font-face stuff is totally new to me and I can’t wait to give it a shot.

    I wanted to pass on a couple links that will add to the info here:

    Finding fonts on your computer:

    And a very detailed walk through of some other options avilable to @font-face:

    Including how find the full and PostScript names using FontBook for Mac or an alternative for PCs. It also talks about how you might use the local() line to define a local copy of one font and use the url to provide a backup, similar to the usual font-family line of backup fonts. For the example, they use helvetica (which would be available on macs) and provide a similar backup for pcs.

    One other big note… Fonts are super easy to get. But check the license before using. You may not have the right to use them, even the ones installed on your computer.

    Good stuff!

  2. David O'Trakoun 2010/04/14 8:47 pm

    You should actually be calling your font-family “Museo” and specifying the “light” part as a font-weight in the @font-face declaration:

    @font-face { /* declare LIGHT WEIGHT fonts */
           font-family: "Museo";
           font-weight: 300;
           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");

    @font-face { /* declare REGULAR WEIGHT fonts */
           font-family: "Museo";
           font-weight: 400;
           src: url("fonts/Museo400-Regular.eot");
           src: local("Museo 400"), local("Museo-300"),
                  url("fonts/Museo400-Regular.woff") format("woff"),
                  url("fonts/Museo400-Regular.otf") format("opentype"),
                  url("fonts/Museo400-Regular.svg#Museo-400") format("svg");

    @font-face { /* declare HEAVY/BOLD WEIGHT fonts */
           font-family: "Museo";
           font-weight: 700;
           src: url("fonts/Museo700-Regular.eot");
           src: local("Museo 700"), local("Museo-700"),
                  url("fonts/Museo700-Regular.woff") format("woff"),
                  url("fonts/Museo700-Regular.otf") format("opentype"),
                  url("fonts/Museo700-Regular.svg#Museo-700") format("svg");

    The CSS font-weights also correspond to semantic names: 100 = light, 400 = normal, 700 = bold. For the Museo family 100 is probably ultra-light or thin. The naming for the particular font is determined by the foundry/type artist.

    I wrote an article on it here:

  3. In the previous article “Quick and Easy CSS @font-face Code” I didn’t believe your code was cross-browsers compatible. I checked it out in Firefox 3.6.3 (mac) and the “I” in I’ve (your first paragraph) didn’t work.

    Today I read this article and the “I” in the first paragraph is working.

    Good news is I now believe you know what your talking about. So, basically I’m reporting a glitch. (:

  4. Kamrul Hasan 2010/05/01 1:21 pm

    I am first time here. Came here to learn WP Custom Fields. And Started to read, read and read. This is my first time here and so a generic comment. Amazing Amazing stuff! I have learned CSS and xHTML from Chris Coyier a lot. But how could I missed your site!
    Many many thanks for teaching us for absolutely free.

  5. I always wondered what that #xxxx was for in the SVG file name. I was confused because the font squirrel generator turned it into “#webfont

  6. Man, thank you for a great article. Would be nice to see a paragraph on browser compatibility though.

  7. Jeff Starr 2010/06/21 3:25 pm

    Max, that is an excellent idea and something I will be discussing more in upcoming articles. Lots more on @font-face in general.

  8. christophe 2010/09/30 7:20 am

    and thank you for these explanation.

    I have an other question about your CSS code below:

    h1 { font: 24px/1 MuseoLight, Verdana, sans-serif; }
    h2 { font: 18px/1 MuseoLight, Verdana, sans-serif; }
    h3 { font: 14px/1 MuseoLight, Verdana, sans-serif; }

    What does mean “font:24px/1” ?

    Thank you

  9. christophe 2010/09/30 7:34 am

    Me again, I found my answer in an other post : the second parameter is for line-height, isn’t it ?


  10. christophe, that is correct – that particular notation is shorthand for “font-size:24px and line-height:1”, combined into one property.

  11. Christophe 2010/10/08 1:52 am

    @Jeff : thx for your reply.
    See you soon

  12. Works like a charm! Thank you!!!

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 »
.htaccess made easy: Improve site performance and security.
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.
Note to self: encrypting 500 GB of data on my iMac takes around 8 hours.
Getting back into things after a bit of a break. Currently 7° F outside. Chillz.
Get news, updates, deals & tips via email.
Email kept private. Easy unsubscribe anytime.