Choosing fonts is a creative and emotional process. Different fonts convey different feelings, and you want a font that complements the tone of your text.

Alternatively, you can also import fonts using an online web font service, such as Google Fonts or Typekit .

Font Loading

Before custom fonts are displayed, they need to be loaded first. There are three possible scenarios for font loading:

The font family is not recognised and a fallback font is applied. The font family is recognised but not yet loaded, and will be applied when it has finished downloading. The font family is recognised and has already been loaded and will be applied immediately.

Scenario 1 only happens when you try to use a nonexisting font, or a declaration with a bad src . This can and should be avoided entirely. Jumping to Scenario 3, it is the best case scenario and can usually be achieved through proper font caching. Scenario 2 is the scenario that involves font loading. Font loading is mostly unavoidable (at least for the first request instance). There are several ways to deal with it:

1. Flash of Unstyled Text ( FOUT ). A FOUT is an instance where a web page uses default and fallback fonts before switching to the proper web font. It happens because font requests do not happen until both HTML and CSS are downloaded. This means that there is a period of time where HTML is displayed before fonts are fully downloaded. The FOUT is the optimal approach for most websites, mainly because the alternatives are a lot worse. When done correctly, a FOUT is hardly noticeable.

2. Flash of Invisible Text ( FOIT ). A number of years ago, some modern browsers started to implement a new technique of dealing with font loading — the FOIT . A FOIT is an instance when the browser detects that a font is currently loading, and hides the text until font loading is complete. There is usually a maximum wait time before the browser switches to a fallback. This approach should always be avoided. Although it might sound good in theory, it can provide an awful user experience for people with slower internet. It can cause a FOUT after the initial FOIT , and at worst can even lead to permanent invisible content.

3. The Whitescreen Approach. The entire web page does not display until fonts are loaded. Alternatively, a loading progress bar can be displayed. This approach is ONLY recommended if a FOUT is going to heavily detract from the user experience of your audience. This is usually the case if the web page heavily relies on very distinct fonts in large sizes. Otherwise, a FOUT is preferred because content is king. This approach is similar to FOIT , but superior because you control when to start showing content instead of the browser. In FOIT , invisible text might also confuse the audience, whereas a completely white screen (or a progress bar) is an obvious sign of loading.

Whether you plan on going with the FOUT approach or the Whitescreen approach, you will want to use a JavaScript library called Web Font Loader. Web Font Loader gives you added control over @font-face, and adds events for you can control the font loading experience.

Note: There is a W3C Font Loading API that achieves similar goals, but its support is still poor.

FOUT Approach

The easiest way to font-load with the FOUT approach is by making use of the recently added font-display CSS property. font-display instructs the browser how the font should be displayed while it is in the downloading state, loading state, or ready state. The value that we want for the FOUT approach is font-display: swap . This tells the browser to render a fallback font until the main font is ready.

@font-face { font-family: 'Helvetica Neue'; src: url('/assets/fonts/HelveticaNeue-Light.eot'); font-display: swap; }

As font-display is still relatively new, browser support for it is limited. Check here to see if your target browsers support it.

A more widely-supported method of achieving FOUT is using JavaScript to append a CSS class once font is ready. Here is an example of this done using Web Font Loader:

<script src="https://ajax.googleapis.com/ajax/libs/webfont/1.6.26/webfont.js"></script> <script type="text/javascript"> WebFontConfig = { google: { families: [ 'Lora' ] } }; </script> <style> p { font-family: "Arial"; } .wf-active p { font-family: "Lora, Arial"; } </style>

In the above code, the browser first renders paragraph texts with Arial. Meanwhile, the Web Font Loader library starts loading Lora from Google Fonts. Once it is loaded, the wf-active class is appended to the html element, and the Lora font starts to be used for paragraph texts.

It is important to use Web Font Loader asynchronously so it does not delay the render of the rest of the page

Style your fallback fonts to appear as close as possible to your actual fonts to minimize the effects of the FOUT . See here for a list of usable fallback fonts. Use this tool to easily compare your fallback font to your custom font.

Whitescreen Approach

Here is an example of using Web Font Loader with the whitescreen approach:

<script src="https://ajax.googleapis.com/ajax/libs/webfont/1.6.16/webfont.js"></script> <script> WebFont.load({ google: { families: ['Raleway', 'Oswald'] } }); </script> <noscript> <link href='https://fonts.googleapis.com/css?family=Raleway|Oswald' rel='stylesheet' type='text/css'> </noscript> <style> .wf-loading { display: none; } .wf-active p { font-family: "Arial"; } p { font-family: "Raleway, Arial"; } </style>

In this case, the fallback does not need to appear similar to your custom font since there is no FOUT . Style the fallback as you see fit.

. Style the fallback as you see fit. Use Pace if you want to include a progress bar instead of a white screen. This is significantly better for UX, especially if the font files are large.

Further Readings: