Web fonts are a great way to give your website a unique design, but embedding all of the necessary font-files can create quite the mess in your CSS. Unfortunately, many of the online tutorials and font-face kit generators give incorrect examples (and are just plain doing it wrong). So, to save you time and fonts-face-related headaches, I’ll show you how to take full-advantage of the font-family, font-weight and font-style properties when using the @font-face embed method.
The wrong way: too many families, not enough weight or style
Lets take a look at a code snippet from one of the kit generators:
@font-face {
font-family: 'ProximaNovaRegular';
src: url('/fonts/proximanova_regular/ProximaNova-Reg-webfont.eot');
src: url('/fonts/proximanova_regular/ProximaNova-Reg-webfont.eot?iefix') format('eot'),
url('/fonts/proximanova_regular/ProximaNova-Reg-webfont.woff') format('woff'),
url('/fonts/proximanova_regular/ProximaNova-Reg-webfont.ttf') format('truetype'),
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: ‘ProximaNovaRegIt’;
src: url(‘/fonts/proximanova_italic/ProximaNova-RegIt-webfont.eot’);
src: url(‘/fonts/proximanova_italic/ProximaNova-RegIt-webfont.eot?iefix’) format(‘eot’),
url(‘/fonts/proximanova_italic/ProximaNova-RegIt-webfont.woff’) format(‘woff’),
url(”/fonts/proximanova_italic/ProximaNova-RegIt-webfont.ttf’) format(‘truetype’),
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: ‘ProximaNovaBold’;
src: url(‘/fonts/proximanova_bold/ProximaNova-Bold-webfont.eot’);
src: url(‘/fonts/proximanova_bold/ProximaNova-Bold-webfont.eot?iefix’) format(‘eot’),
url(‘/fonts/proximanova_bold/ProximaNova-Bold-webfont.woff’) format(‘woff’),
url(‘/fonts/proximanova_bold/ProximaNova-Bold-webfont.ttf’) format(‘truetype’),
font-weight: normal;
font-style: normal;
}
While copy & pasting this into your CSS into your style sheet would technically work, it really isn’t taking full advantage of the css font-specs. If you look through this example, you’ll see that this method created 3 new font-families, one for each weight and style. To style a headline using Proxima Nova Bold, you’ll have to write something like:
h1 {
font-family: 'ProximaNovaBold';
font-weight: normal;
}
Or even worse, if you want to make sure that <em> and <strong> properly style your paragraph text, you’ll have to get awkwardly specific about your fonts in your style sheet:
p {
font-family: 'ProximaNovaRegular';
}
em {
font-family: 'ProximaNovaRegIt';
font-style: normal;
}
strong {
font-family: 'ProximaNovaBold';
font-weight: normal;
}
Knock it off bold
This type of implementation also introduces what we call “faux bold” – when the browser gets confused and tries to force the boldness declared in the stylesheet onto a font-face font declared “font-weight: normal;”. This can be a real problem because most browsers utilize a “base style sheet” — which specifies that certain elements (like headlines) are bold. Remember that h1 from before? That one that you want to be Proxima Nova Bold? You’ll also have to reset the font-weight to normal to save yourself from the wrath of the fake-bolding.
The left image is an example of what happens if you only call font-family: “ProximaNovaBold” — the browser picks up it’s bass style of “font-weight: bold;” and since it can’t find an embedded font in the @font-face declarations that’s labeled bold, creates it’s own, knock-off bold version.
The right image shows what Proxima Nova Bold actually looks like: nice, even boldness. While there is a work-around to fix this faux-bold problem (resetting the browser base styles), it’s not good CSS and could cause problems should the embedded fonts fail to load.
The right way: using font-family, font-weight and font-style to their full capabilities
To save yourself from having to write awkward CSS styles, reset base browser styles, and the scourge of faux-bold, all you have to do is make the proper calls in your @font-face code. The end goal is to neatly organize all coordinating fonts under the same font-family, and simply label their weight and styles.
Here’s the same snippet of code as before, but organized properly (emphasis added where code was changed):
@font-face {
font-family: 'ProximaNova';
src: url('/fonts/proximanova_regular/ProximaNova-Reg-webfont.eot');
src: url('/fonts/proximanova_regular/ProximaNova-Reg-webfont.eot?iefix') format('eot'),
url('/fonts/proximanova_regular/ProximaNova-Reg-webfont.woff') format('woff'),
url('/fonts/proximanova_regular/ProximaNova-Reg-webfont.ttf') format('truetype'),
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: ‘ProximaNova’;
src: url(‘/fonts/proximanova_italic/ProximaNova-RegIt-webfont.eot’);
src: url(‘/fonts/proximanova_italic/ProximaNova-RegIt-webfont.eot?iefix’) format(‘eot’),
url(‘/fonts/proximanova_italic/ProximaNova-RegIt-webfont.woff’) format(‘woff’),
url(”/fonts/proximanova_italic/ProximaNova-RegIt-webfont.ttf’) format(‘truetype’),
font-weight: normal;
font-style: italic;
}
@font-face {
font-family: ‘ProximaNova’;
src: url(‘/fonts/proximanova_bold/ProximaNova-Bold-webfont.eot’);
src: url(‘/fonts/proximanova_bold/ProximaNova-Bold-webfont.eot?iefix’) format(‘eot’),
url(‘/fonts/proximanova_bold/ProximaNova-Bold-webfont.woff’) format(‘woff’),
url(‘/fonts/proximanova_bold/ProximaNova-Bold-webfont.ttf’) format(‘truetype’),
font-weight: bold;
font-style: normal;
}
You’ll notice, all three fonts now fall under the same family, ProximaNova. On top of that, the specifics about their weight and style have been removed from the family name and listed in their proper place, font-weight and font-style.
With this implementation, your style sheet can be a lot cleaner:
p {
font-family: 'ProximaNova';
}
and all of the base browser styles will (hopefully) cooperate, no need to reset anything.
The complicated (and weighted) finish
There may be situations when you have more then just a regular and bold weight. Some font families come with light, semibold, extra bold, and so on and so forth. Luckily for you, this situation is still pretty easy to implement. The font-weight spec accepts a range of numbers (100-900) and all you have to do is assign these accordingly to your @font-face embeds.
Example:
@font-face {
font-family: 'ProximaNova';
src: url('/fonts/proximanova_regular/ProximaNova-SemiBold-webfont.eot');
src: url('/fonts/proximanova_regular/ProximaNova-SemiBold-webfont.eot?iefix') format('eot'),
url('/fonts/proximanova_regular/ProximaNova-SemiBold-webfont.woff') format('woff'),
url('/fonts/proximanova_regular/ProximaNova-SemiBold-webfont.ttf') format('truetype'),
font-weight: 600;
font-style: normal;
}
No big surprise here: using multiple weights isn’t really supported by IE6–8 [insert collective internet-groan]. And of course, the work around tells you to do exactly what we just talked about not doing. I guess sometimes you just have to pick your poison.