FOUT is what I’m calling the flash of unstyled text that you get while using @font-face in Firefox and Opera.
In June, Remy Sharp documented the how a browser progressively renders a page using @font-face. Things work differently between browsers natch:
Here’s how in Firefox; basically the text is in a default webfont until the custom font is ready:
Webkit takes a very different approach, and very intentionally. They believe it’s better to keep the text invisible until the font is ready. This way, there is no moment where the text flashes into its newly upgraded self. (This moment should be familiar to you if you’ve used sIFR)
I really don’t like the text upgrade FOUT, so I personally prefer webkit’s technique. But either way, we want the font loaded ASAP, so let’s speed it up!
Best practices for serving fonts:
- Minimize the overall kilobyte size of your font file. You can reduce the size of your font file by subsetting it (more on this later).
- Heavy caching via a far-future expires header.
Well, no; you can’t gzip a font file, though you can gzip a css file that holds the data-uri representation, but you don’t get much gain there. It’d primarily be an obfuscation technique.
When exactly do browsers download the font file?
Garrick at Kernest tipped me off to IE’s interesting behavior here.
After some research we can see when the asset download is initiated:
- IE will download the .eot file immediately when it encounters the @font-face declaration.
- No browsers download the font file when they find a css rule that references the @font-face font.
- Gecko, Webkit, and Opera all wait until they encounter HTML that matches a CSS rule with a fontstack including the @font-face font.
I’ve put up a test page where you can experiment and watch your dev tools to see when the file is grabbed.
In what cases will you get a FOUT
- Will: Downloading and displaying a remote ttf/otf/woff
- Will: Displaying a cached ttf/otf/woff
- Will: Downloading and displaying a data-uri ttf/otf/woff
- Will: Displaying a cached data-uri ttf/otf/woff
- Will not: Displaying a font that is already installed and named in your traditional font stack
- Will not: Displaying a font that is installed and named using the local() location
Defeat the Firefox FOUT entirely #1: hide the page
The one serious caveat to this technique is: The page will not be visible
until all content, iframes, remote scripts, fonts, and images are downloaded. (I added a three second bailout condition, read below.)
This should run in the
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
2011.04.14 Added note about better technique through targeted selection
First, we are detecting if we’re firefox 3.5+ by seeing if -moz-transform is supported, which was added at the same time. We use visibility:hidden instead of display:none, so that the font will actually be requested, and we remove that style once the page has finished loading. We’re hinging on window load to be our re-entry point, because as Steve Souders pointed out, “font files block the window’s onload event from firing in IE and Firefox, but not Safari nor Chrome.”
I’ve also added a 3 second bailout condition; this means if the page has not completely loaded in three seconds, we’re going to show it anyway. It’s possible the font won’t be ready, but unlikely, I believe. This aims to solve the issue Remy found with the Standards.next site. I wouldn’t recommend it, but you can disable this behavior by commenting out the setTimeout line.
Defeat the Firefox FOUT entirely #2: hide the text
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8
A more lightweight but less effective solution is the
font-size-adjust property, currently only supported in Firefox. It gives you an opportunity to normalize x-height across a font-stack, reducing the amount of visible change in the FOUT. In fact, the Font Squirrel generator just added a feature where it tells you the x-height ratio of the fonts you upload, so you can accurately set the
2009.11.08. Tweaked defeat FOUT code to have a 3 second bailout.
2009.12.14. Added the In what cases will you get a FOUT section.
font-size-adjust(only supported in Firefox) normalizes x-height and may improve the FOUT.
2010.05.26: I removed a bunch of old stuff from this article; it was kinda outdated.
2010.08.24: I updated this article with how to prevent FOUT using the Google Font API’s WebFont Loader.
- Firefox (as of FFb11 and FF4 Final) no longer has a FOUT! Wooohoo! http://bugzil.la/499292 Basically the text is invisible for 3 seconds, and then it brings back the fallback font. The webfont will probably load within those three seconds though… hopefully..
- IE9 supports WOFF and TTF and OTF (though it requires an embedding bit set thing– mostly moot if you use WOFF). HOWEVER!!! IE9 has a FOUT. :(
- Webkit has a patch waiting to land to show fallback text after 0.5 seconds. So same behavior as FF but 0.5s instead of 3s.
And… WebInk has written a small script called FOUT-B-GONE which takes these facts into account and helps you hide the FOUT from your users in FF3.5-3.6 and IE.