Webfonts, CORS, and IE

We do quite a bit of development on the WordPress.com VIP infrastructure, where sites are generally domain-mapped and theme files are loaded over their CDN. Recently we developed a site where the webfont needed was not available through a hosted service, so @font-face was used to include the font files. Once the site was off of our local and staging environments and moved onto WordPress.com, however, we discovered a number of issues concerning the fonts.

Turns out that Firefox and IE9 enforce the Cross-Origin Resource Sharing standard, while as of this writing, other browsers do not. Since we cannot control response headers for WordPress.com to indicate that the fonts should be allowed to load on a domain different from that of the CDN, we chose to use a data URI, or a base64-encoded version of each font file, generated using handy expert mode of Font Squirrel’s @font-face generator.

However, this brought along its own problems – data URIs cannot exceed 32KB in Internet Explorer 8, and are not supported at all in IE 7. In the end, we chose a hybrid route of having a CSS file with the encoded webfonts and another with the webfonts loaded from the URL, with a CSS conditional to only be used for IE8 and below. Everything is enqueued using wp_enqueue_script() so that they load in the correct order, as in the example below. Did you know that you can add IE conditionals to stylesheets?

add_action( 'wp_enqueue_scripts', '10up_enqueue_scripts' );
function 10up_enqueue_scripts() {
	// IE conditional stylesheets
	global $wp_styles;

	wp_enqueue_style( '10up-fonts-ie', get_template_directory_uri().'/css/webfonts.css', false, '1.0' );
	$wp_styles->add_data( '10up-fonts-ie', 'conditional', 'lt IE 9' );

	wp_enqueue_style( '10up-fonts', get_template_directory_uri().'/css/webfonts-encoded.css', false, '1.0' );
	wp_enqueue_style( '10up-main', get_template_directory_uri().'/style.css', array( '10up-fonts-ie', '10up-fonts' ), '1.0' );
}

In an ideal world, we’d set Access-Control-Allow-Origin:* in the response headers when serving the font, but since we can’t in this situation, we did the next best thing. The unfortunate thing with using IE conditionals and wp_enqueue_style() is that the !IE conditional is not properly formatted, as the beginning and end need to be closed and opened as individual HTML comments, and so the rather large encoded fonts stylesheet does end up loaded in IE despite it not being used. As always, there’s a WordPress core Trac ticket for that: #16118. If we see this fixed in the future, then we can make our loading even better. In the meantime, however, we hope this helps if you’ve run into this problem.

Leave a Comment

Finely crafted websites & tools that make the web better.