Report abuse

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
From: http://paulirish.com/2009/fighting-the-font-face-fout/

 I removed a bunch of old stuff from this article; it was kinda outdated. Here it is: 

<div class="update">2010.05.26: 
 Part of this is a little out of date. I'd recommend skipping down to <a href="#defeatthefout">Defeat the FOUT entirely</a> and skip this prioritized download thing that follows. 
 I removed a bunch of old stuff from this article; it was kinda outdated. It's now in an HTML comment if you're really curious. Additionally, the new <a href="http://code.google.com/apis/webfonts/docs/webfont_loader.html">google WebFont Loader</a> can make mozilla behave like webkit and vice versa when it comes to FOUT. I'll update this article later on with how, specifically. :)</div>

<h4>Let's get the font ASAP</h4>
The sooner the better, so let's prioritize getting this font before everything else.

We'll set up our @font-face declaration:
<pre lang="css">
    /* chunk will load immediately in IE at this declaration*/
    @font-face {
    	font-family: 'ChunkFive Regular';
    	src: url('fonts/Chunkfive.eot');
    	src: local('ChunkFive Regular'), local('ChunkFive-Regular'), url('fonts/Chunkfive.otf') format('opentype');
    }
    /* define a class that uses this font */
    .chunk { font-family:'ChunkFive Regular'}
</pre> 

And inside the <code>&lt;head&gt;</code>, we'll include this:
<pre lang="javascript">
(function(className){
    // quit early if we're in IE, no need to do any of this.
    if (/*@cc_on!@*/0) return;
    
    var f = document.createElement('fontdl');
    f.innerHTML = 'fontdl';
    // associate with the @font-face declaration and hide it
    f.className = className;
    f.style.cssText = 'position:absolute; visibility:hidden'
    // it's still off-DOM so it doesn't download yet
    
    // document.body doesnt exist yet so we'll add it onto the HTML tag
    document.documentElement.appendChild(f);
    // font download initiated Now.
    // let's clean up after ourselves (opera needs a timeout > 0)
    setTimeout(function(){f.parentNode && f.parentNode.removeChild(f)},100)  
})('chunk'); // <== pass in the class here.
</pre>

<div class="update">2009.10.10: Based on a tip from my colleague <a href="http://blog.amodernfable.com/">Adam McIntyre</a>, we have a more elegant solution than the above javascript. It, along with more fontstack research, is as follows...</div>

Rather than creating an element on the fly that uses the font, we do the same with HTML:
Adam postulated the we could do the same trick by classing the HTML tag:
(e.g. <code>&lt;html class="chunk"&gt;</code>)
           <ul>  <li>The font-family style won't actually cascade, so no worries about it being inherited by your content</li>
<li>This works in Gecko and Opera, but not Webkit</li>
            </ul>

Alternatively, we add an applicable element to the head: 
<code>&lt;b class="chunk" style="position:absolute; visibility:hidden">download please&lt;/b></code>
         <ul><li>Works in webkit, gecko, opera. Waa hoo!</li>
	<li>Obviously this doesn't validate. FYI, The element will be thrown into the &lt;body> on page load. </li>
</ul>

<h4>Can I pre-load all the font assets?</h4>
So let's say we have more than one @font-face declaration:
<pre lang="css">
@font-face { font-family: 'ChunkFive Regular'; src: local('ChunkFive Regular'), url('fonts/Chunkfive.otf') format('opentype'); }

@font-face { font-family: 'League Gothic'; src: local('league gothic'), url('fonts/LeagueGothic.otf') format('opentype'); }
</pre>
If we set a new class that references both new fonts in a single fontstack, and then pass use that class for our above techniques:
<ul>
	<li>Gecko retrieves all webfonts mentioned in the font stack.</li>
	<li>Opera retrieves all webfonts mentioned in the font stack.</li>
	<li>IE, as mentioned, retrieves them when they're declared, not used.</li>
        <li>Webkit retrieves each font mentioned sequentially until it finds a working one.
                <ul><li>404s and invalid files are considered non-working, of couse.</li>
</ul></li></ul>
So with some CSS like so:
<pre lang="css">
    .chunk { font-family:'ChunkFive Regular'}
    .league { font-family:'League Gothic'}
    .allfonts { font-family: 'ChunkFive Regular', 'League Gothic'; }
</pre>
<pre lang="html4strict">
<!-- preloads both fonts in gecko and opera, webkit only gets the first -->
<b class="allfonts" style="position:absolute; visibility:hidden">download please</b>

<!-- preloads all the fonts in the fontstack in gecko, opera, and webkit -->
<b class="chunk" style="position:absolute; visibility:hidden">download please</b>
<b class="league" style="position:absolute; visibility:hidden">download please</b>
</pre>