Fonts

Bootstrapping of Embedded Fonts to Prevent FOUT

A disclaimer before I start this post – the solution I will present works with best with AJAX applications and can be applied for elements that are not present when the page initially loads.

According to Paul IrishFOUT is what I’m calling the flash of unstyled text that you get while using @font-face in Firefox and Opera.” and this could be quite annoying. Fortunately, on the Internet there are a few good solutions. The issues with the correct (expected) and timely download and application of web-fonts are three:

  1. The actual download of an embedded font starts after the load event of the page;
  2. The downloading of the font will not start until the browser parser encounters elements on the page that atually need this font regardless of the fact that the font is registered in the stylesheet using the @font-face directive.
  3. The font downloading will not start on elements with initial display: none.

Recently I was working on a web project that required the use of embedded fonts, and as the design guys needed a really bullet-proof solution, none of the articles I found was really suitable. Luckily, the project was fully ajax-driven and the embedded fonts were used on elements that were not initially on the page, so the solution I came up with was pretty obvious and easy to achieve – I created a few hidden elements (one for each font), whose font properties required the embedded fonts when page is initially loaded and in this manner the browser was forced to start downloading the font files, so they were available for the “real” elements that needed them later.

The Markup:

<span class="font-loader">
<span class="embedded-font-regular"><!-- / --></span>
<span class="embedded-font-bold"><!-- / --></span>
</span>

The @font-face Directives:

@font-face
{
font-family: "EmbeddedFontRegular";
src: url("../fonts/embedded-font-regular.eot?") format("eot"),
url("../fonts/embedded-font-regular.woff") format("woff"),
url("../fonts/embedded-font-regular.ttf") format("truetype"),
url("../fonts/embedded-font-regular.svg#webfontPPfl10JY") format("svg");
font-weight: normal;
font-style: normal;
}

@font-face
{
font-family: "EmbeddedFontBold";
src: url("../fonts/embedded-font-bold.eot?") format("eot"),
url("../fonts/embedded-font-bold.woff") format("woff"),
url("../fonts/embedded-font-bold.ttf") format("truetype"),
url("../fonts/embedded-font-bold.svg#webfontV2lCDIXN") format("svg");
font-weight: normal;
font-style: normal;
}

The .font-loader rules:

.font-loader
{
visibility: hidden;
position: absolute;
}

.font-loader .embedded-font-regular
{
font-family: EmbeddedFontRegular, Arial, Sans-serif;
}

.font-loader .embedded-font-bold
{
font-family: EmbeddedFontBold, Arial, Sans-serif;
}

Notice that I used position: absolute and visibility: hidden instead of just display: none, because affected browsers would not start downloading the font resources for elements with display: none;

Finally, if you don’t want to add meaningless and non-semantic empty elements on the page, you can easily recreate the solution I have offered with JavaScript that will create the markup on the client from a simple array.

More CSS3, HTML5 and JavaScript experiments on this page.