This article is suitable for anyone out there, from starters to even the most experienced web developers. I’ve seen decade long Senior Web Developers ignoring fonts and not dealing with them properly, so please read along.

After reading a few lines below you will use the correct @font-face and CSS that will work across browsers correctly.

Your website will look and perform as it should across devices.

What are font faces?

I will assume you already know this, otherwise you wouldn’t be reading this article.

However for the sake of information, a @font-face allows for specific fonts to be embedded on a website without having to rely on the remote user having them installed on their system.

The available font types are: “.woff”, “.woff2”, “.ttf”, “.otf”, “.eot”, and “.svg”.

  • .woff stands for Web Open Font Format
  • .woff2 stands for WOFF 2.0 - Web Open Font Format
  • .ttf, .otf stands for TTF/OTF - TrueType and OpenType
  • .eot stands for EOT - Embedded OpenType
  • .svg stands for SVG fonts

Each browser has it’s “own” support for these types (unfortunately), so you need to account for that.

If you want your pages too look the same on all devices and browsers you need all the above formats.

How to correctly use Font Face?

Here’s the tricky part, because if you Google about this even the top websites will not show you the harsh reality.

As mentioned above, each browser has it’s own support for fonts, and if you want your font to work on every browser you have to load the necessary font types and adjust your CSS accordinly.

For example if we checkout Mozilla , you will notice the following:

1@font-face {
2  font-family: "Open Sans";
3  src: url("/fonts/OpenSans-Regular-webfont.woff2") format("woff2"),
4       url("/fonts/OpenSans-Regular-webfont.woff") format("woff");
5}

Is this enough? No, it will not work across all browsers. For example this will not work under Internet Explorer at all.

You can checkout https://caniuse.com/?search=woff2 and see for yourself.

Another example, if we checkout W3 Schools :

1@font-face {
2  font-family: myFirstFont;
3  src: url(myFirstFont.woff);
4}

Is this correct? Still no, it will not support all browsers.

In order to support all browsers your loaded font types and CSS should look like this:

 1@font-face {
 2	font-family: 'FONT';
 3	src: url('FONT.eot'); 									/* IE9 Compat Modes */
 4	src: local(''),
 5       url('FONT.eot?#iefix') format('embedded-opentype'), 	/* IE6-IE8 */
 6       url('FONT.woff2') format('woff2'), 					/* Super Modern Browsers */
 7       url('FONT.woff') format('woff'), 					/* Modern Browsers */
 8       url('FONT.ttf') format('truetype'), 					/* Safari, Android, iOS */
 9       url('FONT.svg#FONT') format('svg'); 					/* Legacy iOS */
10}

Notice the comments on each font type, it’s self explanatory. This will support all browsers and your font will display accordinly.

How to convert and generate Font Face types?

If you are developing a website for a client, they will usually give you one font type. That’s either just .otf or .ttf format, which is not enough.

You need all the formats required for all the browsers out there, so you will need to convert these into the appropiate @font-face types.

Lucky for us, we have online tools to do this automatically and even generate the correct CSS for it (have we evolved or not).

Converting paid/custom Fonts

I recommend you to use Transfonter , but you can of course use whichever you like.

This online free tool will convert your font and provide you with ready to use font types and CSS:

 1@font-face {
 2    font-family: 'Sample';
 3    src: url('Sample.eot');
 4    src: url('Sample.eot?#iefix') format('embedded-opentype'),
 5        url('Sample.woff2') format('woff2'),
 6        url('Sample.woff') format('woff'),
 7        url('Sample.ttf') format('truetype'),
 8        url('Sample.svg#Sample') format('svg');
 9    font-weight: normal;
10    font-style: normal;
11}

Converting free/open source Fonts

In another scenario where your client will not provide you a paid font and instead a free Google Font, there is a tool for this as well: https://google-webfonts-helper.herokuapp.com/fonts .

This tool will also generate the types and CSS necessary to display your fonts correctly on all browsers.

I strongly recommend you to inspect the resulting fonts in different browsers.

How to correctly us Font Families?

I can place a safe bet that you never used the font family specification optimally. Loading the correct font face is not enough, you also need to specify fall back fonts.

Fallback fonts are used when the current font isn’t available. This can happen for several reasons from a CDN issue or a network timeout.

You will notice that most CMS(s) have defined fallback fonts like the following:

1html {
2  font-family: Lato, "Lucida Grande", Tahoma, Sans-Serif;
3}

Is that enough? Uhm, no. Unfortunately systems fonts are not the same on every device. Windows has it’s own, Android has it’s own, iOS as well and so on.

So what to do? Declare them properly, checkout how Bootstrap does it:

 1  // Safari for OS X and iOS (San Francisco)
 2  -apple-system,
 3  // Chrome < 56 for OS X (San Francisco)
 4  BlinkMacSystemFont,
 5  // Windows
 6  "Segoe UI",
 7  // Android
 8  "Roboto",
 9  // Basic web fallback
10  "Helvetica Neue", Arial, sans-serif,
11  // Emoji fonts
12  "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol" !default;

Using the above with custom fonts the outcome would be:

1font-family: "CUSTOM FONT HERE", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";

Now that’s a neat way of dealing of fallback fonts, ensuring your website will look smooth on all devices whilst fonts are loading (or not loading at all).

Testing Font Face and Font Family

Don’t get scared by the word testing, this is a very easy process if you work smart. You don’t even need to inspect the page manually to see what font has loaded (if you are lazy).

As technology evolves, so are the tools available for developers; making life easier and easier to create things.

Checking if your @font-face and font-family is loading correctly is a very easy process, see below.

Checking Font Face and Font Family

  1. Use a browser extension to easily see what font your site is using:
  1. Edit your page and “break” the @font-face, simulating a case when your custom font is not loading. You can “break” the loading by altering the font name or URL which leads to a non-exitent font.
  2. The result should be the first font that matches your device as fallback. For example if you are on a Apple device, this should be “-apple-system”.

Tips and tricks

  • Use the “preconnect” HTML link header tag if you are loading fonts from a CDN.
  • On every font declaration, add font-display: swap; to speedup loading. This instructs the browser to use the fallback font to display the text until the custom font has fully downloaded.
  • Load only the fonts that are actually necessary, I’ve seen people load 7 font types of the same font but only use one of them.
  • To improve page speed, preload the (first or necessary) font using HTTP/2. This will considerably speed up your page and fix the Google PageSpeed “Ensure text remains visible during webfont load”.

Well that’s it, I hope this article has helped you.