Stefan Baumgartner

Web ops, performance and front-end

Preventing FOUT in IE9

16 November 2012 by @ddprrt | Posted in: CSS, Webfonts

FOUT is an abbrevation for flash of unstyled text (or type) and is one of those really nasty bits in modern frontend development. Summarized it means that if you use webfonts it might happen that you first see your text displayed in a fallback font until the downloadble webfont is loaded, parsed and inserted. Remy Sharp and Paul Irish did a lot of research on that topic more than three years ago.

Luckily, with today's browsers you won't be seeing that so often as you might have been used to. The Webkit browsers as well as Firefox are really good in handling Webfonts, and even Internet Explorer, now in version 10, focusses heavily on webfont integration. However, IE10 just came out, and several people -- at least in bigger companies -- are just switching from ancient browsers to IE9...

And IE9 FOUTs. Badly.

In one certain case, after considering server architecture and our clients desktop environment, and even after applying caching routines, this effect was so bad that it wasn't bearable at all. Put there is a certain way of handling this. First of all, we take a look at the currently recommended way of including webfonts for cross browser purposes:

@font-face {
    font-family: 'MySpecialFont';
    src: url('../fonts/MySpecialFont.eot'); /* IE9 compatibility mode */
    src: url('../fonts/MySpecialFont.eot?#iefix') format('embedded-opentype'), /* < IE9 */
         url('../fonts/MySpecialFont.woff') format('woff'), /* Modern browers */
         url('../fonts/MySpecialFont.ttf') format('truetype'), /* iOS, Android, Safari */
         url('../fonts/MySpecialFont.svg#MySpecialFont') format('svg'); /* Legacy iOS */
    font-weight: normal;
    font-style: normal;
}

All modern browsers are capable of handling WOFF, so this should be your format of choice. EOT is more or less just for legacy purposes, and so is TrueType or SVG. So, if you are just reducing your Webfont declaration to the one you need for modern browsers, you end up with this.

@font-face {
    font-family: 'MySpecialFont';
    src: url('../fonts/MySpecialFont.woff');
    font-weight: normal;
    font-style: normal;
}

Maybe you add a fallback for older mobile devices, which know how to handle the comma seperated syntax.

@font-face {
    font-family: 'MySpecialFont';
    src: url('../fonts/MySpecialFont.woff'),
         url('../fonts/MySpecialFont.ttf'),
         url('../fonts/MySpecialFont.svg');
    font-weight: normal;
    font-style: normal;
}

Now, the only browser with FOUT would be IE9 by today's standards. IE9 has the problem that he first loads the stylesheet and then loads the font. The time between those two loading processes can vary. However, if you happen to have the font right here after parsing through the whole stylesheet, you won't get a FOUT. We simply can achieve this by embedding the whole font as a data-URI:

@font-face {
    font-family: 'MySpecialFont';
    src: url("data:application/x-font-woff;base64,MUMBOJUMBO"),
         url('../fonts/MySpecialFont.ttf'),
         url('../fonts/MySpecialFont.svg');
    font-weight: normal;
    font-style: normal;
}

Use a tool like that one for generating those embedded data streams. Now you need to support IE7 and IE8 extra, because IE9 might load the EOT file before checking on the embedded WOFF. We're doing this by creating another Stylesheet, soley for IE legacy purposes. With CSS preprocessors it's a quick thing to do.

@font-face {
    font-family: 'MySpecialFont';
    src: url('../fonts/MySpecialFont.eot');
    font-weight: normal;
    font-style: normal;
}

Seperate those two files by including them in that way:

<!--[if lt IE 9]><link rel="stylesheet" href="../static/css/styleie8.css"><![endif]-->
<!--[if gt IE 8]><!--><link rel="stylesheet" href="../static/css/style.css"> <!--<![endif]-->

The seperating of those browser related stylesheets might not be the most elegant way, but it definitely works and using CSS preprocessors, you won't have that much work in generating those files.

Comments? Shoot me a tweet!