Let’s talk about web fonts. More specifically, about a mistake I have seen developers make in several projects for different agencies: Embedding a web font in the wrong way. In each of the cases, the service they were using was Fonts.com, and given the service’s popularity, this quick tip might come in handy for some people.
So what’s the problem? When you download a font for self-hosting, it often comes with some demo CSS, so that you see how you can use the web font in your project. Fonts.com does that, too. Here is how that CSS code looks like, for example:
/* CSS / Sass */
@font-face {
font-family: "DIN Next LT W01 Regular";
src: url("Fonts/936930ba-a8da-4765-9e89-0f35cdff223f.eot?#iefix");
src: url("Fonts/936930ba-a8da-4765-9e89-0f35cdff223f.eot?#iefix")
format("eot"),
url("Fonts/6b4d4830-9c7d-43d2-b5d3-c73f739561b9.woff2") format("woff2"),
url("Fonts/ccf25ada-6d2a-4133-95dc-deb039e22999.woff") format("woff"),
url("Fonts/126195b4-2fa0-4b95-b5cf-ad9bf10193f0.ttf") format("truetype"),
url("Fonts/58fc798b-98f9-4485-8d2b-7b93a71ee2a6.svg#58fc798b-98f9-4485-8d2b-7b93a71ee2a6") format("svg");;
}
@font-face {
font-family: "DIN Next LT W01 Bold";
src: url("Fonts/fa5ed46b-792d-4f47-894e-fa587cf4e1cf.eot?#iefix");
src: url("Fonts/fa5ed46b-792d-4f47-894e-fa587cf4e1cf.eot?#iefix")
format("eot"),
url("Fonts/03008527-67bd-478e-98e3-3b56dd9a6520.woff2") format("woff2"),
url("Fonts/557f817d-9c25-4a23-baaf-a3cf84a7cd7c.woff") format("woff"),
url("Fonts/92ed1479-1d40-4a94-8baf-6abd88b17afa.ttf") format("truetype"),
url("Fonts/03008527-67bd-4485-8d2b-7b93a71ee2a6.svg#03008527-67bd-4485-8d2b-7b93a71ee2a6") format("svg");;
}
First of all, you might not need the older file formats EOT, SVG, and even TTF. Modern browsers all understand WOFF of WOFF2, so let’s get rid of the rest.
/* CSS / Sass */
@font-face {
font-family: "DIN Next LT W01 Regular";
src: url("Fonts/6b4d4830-9c7d-43d2-b5d3-c73f739561b9.woff2") format("woff2"),
url("Fonts/ccf25ada-6d2a-4133-95dc-deb039e22999.woff") format("woff");
}
@font-face {
font-family: "DIN Next LT W01 Bold";
src: url("Fonts/03008527-67bd-478e-98e3-3b56dd9a6520.woff2") format("woff2"),
url("Fonts/557f817d-9c25-4a23-baaf-a3cf84a7cd7c.woff") format("woff");
}
Much better already. Also make sure that WOFF2 comes before WOFF so that browsers which support the 30 % smaller WOFF2 format will use it.
But back to the initial problem. When you wanted to use the fonts defined in the code above, you would reference the font-family
from the @font-face
rule like so:
/* CSS / Sass */
p {
font-family: "DIN Next LT W01 Regular", sans-serif;
}
strong {
font-family: "DIN Next LT W01 Bold", sans-serif;
}
Can you see the problem? No? There are actually two problems this creates. The first one is that by only using a separate font-family for each font-weight, you are creating faux-bold text. In the example above, the browser will artificially add an extra bit of “boldness” to all text that is marked up with strong
. That’s clearly not what we want, so I have seen people simply adding a font-weight
rule to their code:
/* CSS / Sass */
p {
font-family: "DIN Next LT W01 Regular", sans-serif;
font-weight: normal;
}
strong {
font-family: "DIN Next LT W01 Bold", sans-serif;
font-weight: normal;
}
Problem solved! Well, no, not really. Now our strong text will be rendered with the bold font without any additional weight – but only if the web font successfully loads. When the download fails (or a user uses a content blocker to block web fonts from loading) our strong text suddenly isn’t bold at all. It is as normal-looking as the rest of the text.
And there’s another problem. Sometimes, people don’t even bother to use the right font-family for elements that should have bold text or are rendered in bold via the browsers default styles.
/* CSS / Sass */
body {
font-family: "DIN Next LT W01 Regular", sans-serif;
font-weight: normal;
}
strong {
font-weight: bold;
}
It might not be immediately visible to the untrained eye, but any seasoned designer or typographer will see the difference. Strong is now faux-bold again. Because the regular weight is used for the whole body, the strong element will get the bold font of the family. But in this case, the family is "DIN Next LT W01 Regular" and a bold font does not exist. So the browser will faux-bolden the text. Not only does this change the contrast and letterforms of the typeface and thus look clunky and unprofessional, it even can create this:

Paul Renner’s Futura is a font with sharp edges. Different browsers will give their best to artificially make the font bolder. But you will end up with distorted proportions and shapes.
There is one simple solution to all of those problems: Properly define a font-family with different font-weights and font-styles in your @font-face
declarations. Instead of using a font-family for each font, use the same family name for all fonts and tell the browser which weight (and style) it is:
/* CSS / Sass */
@font-face {
font-family: "DIN Next LT W01";
src: url("Fonts/6b4d4830-9c7d-43d2-b5d3-c73f739561b9.woff2") format("woff2"),
url("Fonts/ccf25ada-6d2a-4133-95dc-deb039e22999.woff") format("woff");
font-weight: 400;
font-style: normal;
}
@font-face {
font-family: "DIN Next LT W01";
src: url("Fonts/03008527-67bd-478e-98e3-3b56dd9a6520.woff2") format("woff2"),
url("Fonts/557f817d-9c25-4a23-baaf-a3cf84a7cd7c.woff") format("woff");
font-weight: 700;
font-style: normal;
}
And that’s it! Now, your strong text – or also your headlines, if you like – will use the bold font-weight and also have the correct fallback font in case the web font doesn’t load. The same goes for italic or cursive fonts.
Unless you are using a JavaScript-based web font loading strategy, you might also add font-display: swap
to the code. By that you opt-in to so-called FOUT (Flash of Unstyled Text) on browsers with support for font-display. So while the site loads, the fallback font is shown first, and as soon as the web font has been downloaded, the fallback font is swapped with the new one.
/* CSS / Sass */
@font-face {
font-family: "DIN Next LT W01";
src: url("Fonts/6b4d4830-9c7d-43d2-b5d3-c73f739561b9.woff2") format("woff2"),
url("Fonts/ccf25ada-6d2a-4133-95dc-deb039e22999.woff") format("woff");
font-weight: 400;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: "DIN Next LT W01";
src: url("Fonts/03008527-67bd-478e-98e3-3b56dd9a6520.woff2") format("woff2"),
url("Fonts/557f817d-9c25-4a23-baaf-a3cf84a7cd7c.woff") format("woff");
font-weight: 700;
font-style: normal;
font-display: swap;
}
Done.
Final remark: There might be one situation in which using faux-bold text might actually be useful and justified. If you are using a two-stage font loading strategy as Zach Leatherman did for CSS-Tricks. It basically means that you are splitting your web fonts into a smaller chunk and a larger lazy-loaded chunk, for example by loading the regular version of the font first and showing the faux-bold text to your users until the real bold font-weight arrives. By that, you can mitigate text movement across the page a bit as soon as your web fonts are loaded and the text reflows.
–
This is the sixth post of my 100 days of writing series. You can find a list of all posts here.
~