How to Be Notified Once a Web Font Has Loaded

Wait for fonts to load before rendering web page

This is down to how the browser behaves.

First off where is your @font declared? Is it inline to your HTML, declared in a CSS sheet on the page, or (hopefully) declared in an external CSS sheet?

If it is not in an external sheet, try moving it to one (this is better practice anyway usually).

If this doesn't help, you need to ask yourself is the fraction of a second difference really significantly detrimental to the user experience? If it is, then consider JavaScript, there are a few things you might be able to do, redirects, pauses etc, but these might actually be worse than the original problem. Worse for users, and worse to maintain.

This link might help:

http://paulirish.com/2009/fighting-the-font-face-fout/

How to know if a font (@font-face) has already been loaded?

Now on GitHub: https://github.com/patrickmarabeas/jQuery-FontSpy.js

Essentially the method works by comparing the width of a string in two different fonts. We are using Comic Sans as the font to test against, because it is the most different of the web safe fonts and hopefully different enough to any custom font you will be using. Additionally we are using a very large font-size so even small differences will be apparent. When the width of the Comic Sans string has been calculated, the font-family is changed to your custom font, with a fallback to Comic Sans. When checked, if the string element width is the same, the fallback font of Comic Sans is still in use. If not, your font should be operational.

I rewrote the method of font load detection into a jQuery plugin designed to give the developer the ability to style elements based upon whether the font has been loaded or not. A fail safe timer has been added so the user isn’t left without content if the custom font fails to load. That’s just bad usability.

I have also added greater control over what happens during font loading and on fail with the inclusion of classes addition and removal. You can now do whatever you like to the font. I would only recommend modifying the fonts size, line spacing, etc to get your fall back font as close to the custom as possible so your layout stays intact, and users get an expected experience.

Here's a demo: http://patrickmarabeas.github.io/jQuery-FontSpy.js

Throw the following into a .js file and reference it.

(function($) {

$.fontSpy = function( element, conf ) {
var $element = $(element);
var defaults = {
font: $element.css("font-family"),
onLoad: '',
onFail: '',
testFont: 'Comic Sans MS',
testString: 'QW@HhsXJ',
delay: 50,
timeOut: 2500
};
var config = $.extend( defaults, conf );
var tester = document.createElement('span');
tester.style.position = 'absolute';
tester.style.top = '-9999px';
tester.style.left = '-9999px';
tester.style.visibility = 'hidden';
tester.style.fontFamily = config.testFont;
tester.style.fontSize = '250px';
tester.innerHTML = config.testString;
document.body.appendChild(tester);
var fallbackFontWidth = tester.offsetWidth;
tester.style.fontFamily = config.font + ',' + config.testFont;
function checkFont() {
var loadedFontWidth = tester.offsetWidth;
if (fallbackFontWidth === loadedFontWidth){
if(config.timeOut < 0) {
$element.removeClass(config.onLoad);
$element.addClass(config.onFail);
console.log('failure');
}
else {
$element.addClass(config.onLoad);
setTimeout(checkFont, config.delay);
config.timeOut = config.timeOut - config.delay;
}
}
else {
$element.removeClass(config.onLoad);
}
}
checkFont();
};

$.fn.fontSpy = function(config) {
return this.each(function() {
if (undefined == $(this).data('fontSpy')) {
var plugin = new $.fontSpy(this, config);
$(this).data('fontSpy', plugin);
}
});
};

})(jQuery);

Apply it to your project

.bannerTextChecked {
font-family: "Lobster";
/* don't specify fallback font here, do this in onFail class */
}

$(document).ready(function() {

$('.bannerTextChecked').fontSpy({
onLoad: 'hideMe',
onFail: 'fontFail anotherClass'
});

});

Remove that FOUC!

.hideMe {
visibility: hidden !important;
}

.fontFail {
visibility: visible !important;
/* fall back font */
/* necessary styling so fallback font doesn't break your layout */
}

EDIT: FontAwesome compatibility removed as it didn't work properly and ran into issues with different versions. A hacky fix can be found here: https://github.com/patrickmarabeas/jQuery-FontFaceSpy.js/issues/1

How can I detect when a google web font is ready and displayed in the page?

Not sure if this is what you need but you may give it a try. If you use WebFont Loader then may be you can track it.

The WebFont Loader is a JavaScript library
that gives you more control over font loading than the Google Web
Fonts API provides. The WebFont Loader also lets you use multiple
web-font providers. It was co-developed by Google and Typekit.

You can do it using some callbacks like loading(), active(),
fontactive(fontFamily, fontDescription) e.t.c. or checking some class
attributes.

Here it is, hope it'll help you.

How to know when font-face has been applied

I found a solution after wondering why IE doesn't suffer from this problem.

Firefox and Chrome/Safari triggers the DOMContentLoaded event before font-face is applied, thus causing the problem.

The solution is to not listen for DOMContentLoaded but instead go oldschool and listen to onreadystatechange and wait until the document.readyState === 'complete' which is always triggered after font-face is applied (as far as I can tell by my tests) - which is of course what always happens in IE since it doesn't support DOMContentLoaded.

So basically you can roll-your-own event in jQuery called fontfaceapplied - maybe it should be built in ;)

document.onreadystatechange = function() {
if (document.readyState === 'complete')
$(document).trigger('fontfaceapplied');
};

Funny fact: Opera does it right and waits to trigger DOMContentLoaded until font-face is applied.

How to wait for webfonts to load?

If you embed the fonts through the "WebFont Loader" (used by Google and Typekit), you can subscribe to the active event. It will be fired once all fonts have been loaded.

Have a look at the docs: https://developers.google.com/webfonts/docs/webfont_loader#Events

Using jQuery to know when @font-face fonts are loaded?

Ok, it was pretty easy. Basically I just set my text to:

a.main {visibility: hidden;}

and then add:

$(window).bind("load", function() {
$('#nav a.main').addClass('shown');
});

Then make sure that the following is also in my css file:

a.main.shown {visibility: visible;}

Is a js event emitted when a css font is swapped?

Yes you can do this with Font Face Observer which is a small @font-face to monitor the load of the font. This does not restrict you using any type of font loading.

for example

var font = new FontFaceObserver('My Family', {
weight: 400
});

font.load().then(function () {
console.log('Font is available');
}, function () {
console.log('Font is not available');
});

If you want more information check out https://portalzine.de/dev/options-to-detect-when-a-font-face-has-been-loaded/

Hope that answered your question.



Related Topics



Leave a reply



Submit