Main navigation

How to use @font-face to avoid faux-italic and bold browser styles

Did you know that if you declare a custom font using @font-face, the browser will try to fake the bold and italic styles if it can’t find them? This is a clever little feature that avoids a scenario where a themer specifies a font and is then confused that bold and italics don’t work, but it can be very confusing if you actually have a bold or italic version of the font. In this article, I’ll walk you through how to properly load your font files to avoid the browser’s faux-italic and faux-bold styles.

(If you’re not interested in an explanation of the problem or the bad solution recommended by most font-embedding services, go ahead and skip down to The Right Solution.)

The Problem

First, to clarify: A font is a file containing a particular typeface, which is a particular weight or style of a type family. eg, garamond-bold.ttf is the font copy of Garamond Bold, a typeface from the Garamond family. In CSS terms, you load a font file using @font-face declarations, which append that font to a font-family.

The problem, as you can see in this screenshot, is that if you only load one font into the family, then the browser doesn’t know what to do when it’s asked to render a bold or italic section using that font. It solves this by creating a faux-bold style by stretching the letters horizontally, and a faux-italic style by slanting the letters.

fig a: comparison of faux browser styles and true typefaces

The browser’s brute-force approach to creating these faux styles leaves a lot to be desired. In particular, note the proper italic font includes a variant lowercase ‘a’ without the ascender, and bold characters have an even thickness to the stroke, rather than the wider vertical strokes on the faux-bold.

The Wrong Solution

The common technique shared by many font services like FontSquirrel or WebINK is to create additional @font-face declarations, creating a new font-family definition for each font weight and style. Then you apply the regular font to the target, and write rules to apply the bold or italic fonts on any nested elements, like so:

And it seems to work perfectly! Your custom bold and italic fonts are loaded properly, and the faux styles are nowhere to be seen! The problem is that if your custom font doesn’t load for some reason, the browser is no longer applying bold or italic styles to the fallback font.

fig c: no bold or italic styles if custom font fails to load

So I think we can agree that this solution doesn’t work. It requires a lot of CSS to override built-in browser styles, and it breaks completely when the custom font doesn’t load. Luckily, there’s a better solution:

The Right Solution

Instead of defining separate font-family values for each font, You can use same font-family name for each font, and define the matching styles, like so:

Then all you need to do is apply that single font-family to your target, and any nested bold or italic styles will automatically use the correct font, and still apply bold and italic styles if your custom font fails to load.

fig d: properly defined italic and bold fonts with fallback styles

You can see a live example of these problems and the final solution on the demo page.

Seriously, Microsoft?

fig e: comparison of @font-face on Macintosh and Windows XP

Also, I know it’s old news that type rendering on Macintosh is better than Windows, but seriously, when I see results like this (look at the lowercase ‘d’ – it’s a travesty!), I consider telling my clients it’s not worth it, because their beautiful custom fonts are going to look awful to over half the visitors to their website. I’ve heard Windows 7 has better rendering, but I don’t have a copy to test. All I can do at this point is trust that things will continue to improve, and enjoy how pretty things look on my Mac.

I love when front-end guys and designers comment on stuff like the lower case d. I mean, I see that it's different but I don't see how it's a travesty. Okay, actually travesty is the exact right definition but I feel like most people define travesty as something closer to anathema or heresy rather than just gross mockery.

Anyways, insightful and smart as usual. You're such a rockstar it hurts sometimes.

hello,
thank you for this post.
it is solving the exact problem i am having-- only not quite.
if you go to my linked site (rikedoepp.com)
you can see that the italic font loads first, then is changed to a non-italic font immediatley after.
do you know what may be causing this?

Hm, and is there a way to force that faux italic? Font I am using doesn't have italic so I would love browser to make it that way. But when I define the font, the browser won't do that. When I use it locally from my PC (without defining by @font-face) it can make faux italic.

Just wondering: what if I want to define some text as bold using CSS and not using the strong tag? For example, if I want my navigation menu to be bold text. It makes more sense to define that in my CSS file rather than using strong tags. So in this case, how do I define it using a properly embedded web font, i.e. "The Right Solution" above?

Ya know, I'm usually picky about code but with the @font-face embedding I just grabbed the Font Squirrel stuff and threw it in with nary a problem. Until today. Then I Googled and found out a better way to handle the CSS. You helped fix my problem and avoid future issues. Thanks!

This problem (the double-bolding/italicing vs. the no fallback) has been bugging me for months, since we started using webfonts.fonts.com for some sites at my job. It was nice to find this blog post. Unfortunately, the developer is not able to change the font-family names to be the same when using this service, so I don't think there is a way to implement this solution. I will contact them with the suggestion. Thanks for the post!

Great Scott! Thanks for a great explanation to this issue. However, what about me who uses CSS reset for all my projects? I don't like to have differing browser styling playing around with the layout, however in this case it results in a matter of specificity. Am I missing something out or do I just have to cope with typography related browser styling?

@Stojjan: 14 typefaces should be no problem. Here's an example using Open Sans on Font Squirrel, which comes in five weights (including italics for each, for 10 typefaces total). Note that I've assigned the "regular" typeface to font-weight: 400, and "bold" to font-weight: 700 -- you could also use font-weight: normal and font-weight: bold -- the spec say normal is 400 and bold is 700.

The examples in the blog post are abbreviated for clarity, but this is the full code, including loading all the different font files for each typeface: TTF for modern browsers, EOT for IE, WOFF for future-proofing, and SVG for iOS (though that's not needed anymore, since iOS now reads TTF).

You mentioned that the examples I provided don't work in IE -- I've never had that problem. In fact, I'm using this technique on all the sites I work on.

The key is simply to make sure that all the @font-face rules declare the same font-family value, with unique font-weight and font-style combinations.

I have Helvetica installed on my Windows 7 system and I use Firefox as my primary browser. This leads to some problems whenever a website specifies "helvetica, arial" in its css, because Helvetica is rendered especially poorly in Firefox at small sizes.

So, a common solution is to hack the userContent.css file in your Firefox profile folder and add such things as

I specified rules for Helvetica, Helvetica Neue and HelveticaNeue just to be sure: I noticed all three forms are found in css sheets around the web. There might be more, so my script is probably not exhaustive. Just add the relevant cases whenever applicable.

Hi, thanks Scott. And all the people who posted the comments. I was strugling with @font-face. Especially with bold and italic. I tried the fontsquirl package. Didn't work right. But the solucion of valerio on June 17, 2012 works perfect. My client is very happy now. ;)

The reason why Fontsquirrel and the like have been using the "wrong solution" is a bug on IE 9 and 10 in compatibility mode. The "right solution" works perfectly on IE 7 and 8 and I had been using it until the release of IE 9 but they don't render at all on IE 9 and 10 in compatibility view unless you use the "wrong solution". I know most people shouldn't be using compatibility view anyway but it's pretty easy to activate by accident and some people are stuck in that mode without even knowing it. If you want your fonts to render correctly for those people, you have to use the "wrong solution", even though it can be a real pain sometimes.

I was just trying to block all those awful-looking Web fonts that are anti-aliased/"smoothed".
I'm using Stylish (Firefox extension) in Pale Moon and your solution worked to finally make my rules apply to bold and italic styles too!!
Thanks a million!!