Google's Font API is a great new addition to the arsenal of the HTML5/CSS3 developer - however there is one drawback to adding web fonts to a page: The font download will be initiated during the page load and may take longer than the browser needs to render the page. The result is FOUT: Flash Of Unstyled Text.
I've seen heroic attempts to describe FOUT as a feature - after all the user sees the text instantly and doesn't have to wait for the fancy font to load, but, frankly, I'm not buying it. The text will first appear in one of the standard web fonts and then after a few seconds the page - not sure what the word here should be - contracts to its final form. Clearly this will be an issue, even if most developers are willing to ignore FOUT, our clients will be more than happy to discuss their reactions to such a page load behaviour.
Here are three implementation examples, the first one without any fixes for FOUT, and two different solutions for the problem that both essentially hide the text until the fonts are ready to be rendered.
You may also be interested in some of my other articles around HTML5, CSS3 and JavaScript.
Simple Webfonts Example
Using CSS to Hide FOUT
Here we use the JavaScript WebFont Loader to load the fonts and CSS to hide the text until the fonts are done loading. The API signals the current status of the font loading operation with classes that it applies to the HTML object in the page.
During the load operation wf-inactive class is applied, and on success it is replaced with wf-active. Our text is by default several thousand pixels off-screen to the left, and a CSS rule dependent on wf-active will then move the text into the visible area of the page when the API signals success.
Relevant Code:
<script src="http://ajax.googleapis.com/ajax/libs/webfont/1/webfont.js"></script>
<script>
WebFont.load({
google: {
families: [ 'Josefin+Sans+Std+Light', 'Cantarell' ]
}
});
</script>
<style>
p {
font-family: 'Cantarell', sans-serif;
margin-left: -2000px;
}
h1 {
font-family: 'Josefin Sans Std Light', sans-serif;
margin-left: -2000px;
}
html.wf-active h1, html.wf-active p {
margin-left: 0px;
}
#loader {
position: absolute;
left: 320px;
top: 80px;
}
html.wf-active #loader {
left: -2000px;
}
</style>
Using JS to Hide FOUT
This example looks and behaves similar to the previous one, but here we have ultimate control over how the fully rendered text will be revealed.
As before, we use Google's WebFont Loader API to load the fonts, but in addition we have added several event handlers and MooTools to control the opacity of the text elements and to add a little fade animation when the text is ready. We actually only use the 'active' event handler in this example, both the 'loading' and 'inactive' handlers are just placeholders.
Relevant Code:
<script src="includes/mootools-1.2.4-core.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/webfont/1/webfont.js"></script>
<script>
WebFont.load({
google: {
families: [ 'Josefin+Sans+Std+Light', 'Cantarell' ]
},
loading: function() {
// do something
},
active: function() {
$('loader').fade('out');
$('header').fade('in');
$('maincontent').fade('in');
},
inactive: function() {
alert('uh-oh...');
}
});
function init_page() {
$('header').setStyle('opacity','0');
$('maincontent').setStyle('opacity','0');
}
window.onload = init_page;
</script>
<style>
body {
margin: 0px;
text-align: center;
background-color: #e0e0e0;
font-family: Helvetica, Arial, sans-serif;
color: #333333;
font-size: 62.5%;
}
#container {
position: relative;
margin-left: auto;
margin-right: auto;
width: 660px;
padding-bottom: 5px;
text-align: left;
background-color:#ffffff;
margin-top: 15px;
font-size: 1.4em;
}
#loader {
position: absolute;
left: 320px;
top: 80px;
}
#header {
padding: 5px 0 0 20px;
opacity: 0;
}
#maincontent {
padding: 0 40px 0 20px;
text-align: justify;
opacity: 0;
}
.wf-active p {
font-family: 'Cantarell', sans-serif;
}
.wf-active h1 {
font-family: 'Josefin Sans Std Light', sans-serif;
}
</style>
This is a simple implementation of the Google Font API without the use of JavaScript based on the official tutorial. This example tends to display FOUT behaviour on load, expecially in Firefox. As Paul Irish has pointed out in his comprehensive tutorial page, Webkit automatically hides all text that is dependent on web fonts until the fonts have been loaded, so FOUT is less of a problem there.
Relevant Code: