Inline Web Font to Avoid FOUT
Nov 10, 2016
Web fonts enable designers and developers to create great looking websites. The decision to use a web font is easy. But the decision of how to load the web font may not be that easy. In this post we’ll quickly review the issue of FOUT (flash of un-styled text) when loading a web font asynchronously, and then I will show you how you can inline the web font data using a Base64 string.
If you are new to web development and CSS3 I recommend you check out Webucator’s CSS3 training.
Using Web Fonts
While web fonts are awesome, the use of a web font in your web application or in your website design requires that your user downloads the font file. A font file contains the data that instructs the browser how to display the font. The most common “file”, or encoding of a font, is called the Web Open Font Format (WOFF), and it can be used by most modern browsers.
@font-face CSS property, we can load font files into our browser to be displayed. Here is a common approach to load the web font files necessary to support a broad range of browsers:
src: url('webfont.eot'); /* IE9 Compat Modes */
src: url('webfont.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('webfont.woff2') format('woff2'), /* Super Modern Browsers */
url('webfont.woff') format('woff'), /* Pretty Modern Browsers */
url('webfont.ttf') format('truetype'), /* Safari, Android, iOS */
url('webfont.svg#svgFontName') format('svg'); /* Legacy iOS */
This is an example of using the
@font-face property as shown by css-tricks.com.
This works well when we are blocking the rendering of our page by loading our CSS synchronously. Let me explain. When your stylesheet is loaded using the traditional approach using a
<link> tag with the
rel attribute to “stylesheet”, the browser will block the rendering of your page until the CSS file is downloaded and parsed. When the browser parses the
@font-face property it will then initiate a request for the appropriate font file (in most cases the .woff file). While this works, it has a major flaw. During all of this time your user is waiting.
If you use the Google PageSpeed Insights tool you will get a notification that says:
Your page has 3 blocking CSS resources. This causes a delay in rendering your page.
None of the above-the-fold content on your page could be rendered without waiting for the following resources to load. Try to defer or asynchronously load blocking resources, or inline the critical portions of those resources directly in the HTML.
Google PageSpeed Insights suggests that we should optimize the delivery of our CSS:
Identify and inline the CSS necessary for rendering the above-the-fold content and defer loading the remaining styles until after the above-the-fold content is rendered.
OK, that shouldn’t be too difficult. First, determine the critical (or necessary) CSS that is needed to render the above-the-fold content. Once we have that done then we should defer the loading of the rest of our application’s CSS. When we say defer, we should think asynchronously.
In order to defer the loading of your CSS you will want to put off the downloading and parsing of your site’s non-critical CSS until after the page has been rendered. To do that we can use the Web Font Loader project. This enables us to load CSS after our page has been loaded and rendered. It is free to use and was created as a joint project between Google and Typekit.
But what if our web font is critical? Meaning that the web font is necessary to display the above-the-fold content on our website. The answer is that we can put the font file data inline using the Base64 encoding of the binary data in ASCII format.
If we do not inline our font file data then we will notice a “flash of un-styled text”, or FOUT. The browser will first render the fallback font and then after the deferred font is loaded it will replace the un-styled text with our fancy web font. This can happen very quickly for most users, but it can also be distracting and not very easy on the eyes.
In the example above, we specified the URL for each of our font files. The browser then used the resource location to download the appropriate file. Using the data URI specification we can embed the font file data (in Base64 format) inline in our CSS.
Here is the Data URI syntax:
We can use the data URI for the source of our
@font-face. Here is an example with the Base64 string removed (it’s quite long):
src: url(data:font/woff;charset=utf-8;base64,<base64 string>) format('woff');
In the code above we are still specifying the src of the
@font-face and we are still using the
url() method. But inside there we use the
data URI to inline the font file using the Base64 encoding.
Converting to Base64
OK, so we now know how to inline our web font using the Base64 encoding of the font file. But how do we get the Base64 string from our font file? On a Mac we just need to run a couple of commands. On Windows you will also need to download an executable command from Microsoft.
If you are using a Mac, the
base64 command is built into the bash shell:
$ base64 mywebfont.woff > mywebfont.woff.b64
$ pbcopy < mywebfont.woff.b64
The above commands will create a file that contains the Base64 string using the
base64 command. We then copy it to the clipboard via the
pbcopy command. Then, paste this string where the placeholder
<base64 string> is in the above
Having our font embedded in our inline CSS that ships with our HTML enables us to instantly render the page without FOUT.