@font-face not working without custum .htaccess declaration

Jan 14, 2010 0 Comments
Tagged: , , and

I recently started using @font-face in a major website. The time has come to free ourselves from the shackles of the webfonts. I got the chance to host the fonts on a amazon s3 cloudfront instance. Really fast and with the 'bullet-proof @font-face' solution of Paul Irish I decided to give it a go.

So I started testing and everything looked very promising, even the FOUT wasn't too bad. But when we got around to implementing it in the real templates for the site, my esteemed colleague Maarten found a flaw.

It seems that the .otf file that we use isn't being read properly in Firefox, but instead gives a weird error.

Failed to load source for: http://wnas.nl/fonts/FrescoStd-Normal.otf 

Safari uses the same .otf file and displays it properly. But with this CSS:

@font-face { 
font-family:'FrescoStdNormalRegular';
src: url('http://wnas.nl/fonts/FrescoStd-Normal.eot');
src: local('no local - Fresco Std Normal Regular'),local('no local-FrescoStd-Normal'),
url('http://wnas.nl/fonts/FrescoStd-Normal.woff')
format('woff'),
url('http://wnas.nl/fonts/FrescoStd-Normal.otf')
format('opentype'),
url('http://wnas.nl/fonts/FrescoStd-Normal.svg#FrescoStd-Normal')
format('svg');
}
#test{
font-family:FrescoStdNormalRegular,courier;
}

FrescoStdNormalRegular,courier;

Firefox, as you can see, just doesn't render the font, can anyone help me and point out what I am doing wrong? Please let me know in the comments...

Update

It seems that this does work on my website, but not locally... Here is a test page where I get two different responses from firefox 3.5.7 on os X 10.6.2.

  • on the Imac it says : The resource from this URL is not text: http://wnas.nl/fonts/FrescoStd-Normal.otf
  • And the macbook pro says: Failed to load source for: http://wnas.nl/fonts/FrescoStd-Normal.otf

Get the source from here and let me know what happens on your machines through the comments or twitter.

#WIN

Thanks to Jeroen who at least does some research, before asking the rest to help, we have a cause and a solution. On the mozzilla page about font-face it states:

By default, Firefox 3.5 only allows fonts to be loaded for pages served from the same site.

So you should set this in your .htaccess file and you're right as rain.

# example Apache .htaccess file to add access control header

<FilesMatch "\.(ttf|otf)$">
<IfModule mod_headers.c>
Header set Access-Control-Allow-Origin "*"
</IfModule>
</FilesMatch>

Thanks everybody for helping, I hope someone else benefits from this as well. I just learned something new, the main reason I really like my job!

Light at the end of the tunnel

May 05, 2009 0 Comments
Tagged: , , , and

After years of domination, finally IE's share is starting to slide down to a respectable level. Web developers rejoice! Go and read for your self here:

Internet Explorer's progressive slide continues: Microsoft's browser is down to 66.10 percent from 73.01 percent a year ago. Half of that loss has been taken up by Firefox (up from 19.03 to 22.48 percent), with Safari also benefiting (up from 6.31 to 8.21 percent).

See the source

And as for mobile, it seems even better for us:

If the breakdown is restricted to mobile platforms, the shares are (to the nearest whole number) iPhone/iPod touch 65 percent, Android 9 percent, Java ME 8 percent, Symbian 7 percent, Windows Mobile 6 percent, BlackBerry 3 percent, others 2 percent.

See the source

But as a word of warning, this may look good. But in my opinion we still have to cater some content to IE6 users, as each user is as important as the others. It just mean that we will have to jump through less hoops, as hopefully customers will be using a better browser than IE6.

Console.log for IE

I write a lot of javascript in my present project. Doing this, I just love firebug and more to the point the console.log function that it lets me use. Bummer is only that it doesn't work in IE, the one browser that needs javascript debugging most. It also throws javascript error in IE when used. That is something that can be avoided by cleanly remove all of those console.log statements before you send stuff to be tested.

But, as everybody knows in the real world people tend to forget such things. So in annoyance with these errors, I set out to recreate the basis console.log function for IE as well. In retrospect it turns out that I set out to create a better mouse trap, but hey, it was fun and good enough to share, so lets...

In my solution and do not worry, I will share other solutions but first I will speak my mind. The console.log function is not used, instead you use logger(message). This sends the message to message to the console, if there is any, or it creates an ul (with an id of 'logger') in which it sets li's with the individual messages. So without further ado, I present to you the code:

 /*
* wilfred nas
*
* info@wnas.nl
* http://www.wnas.nl/
* http://snippets.wnas.nl/
*/

// to intitialize the logger set : var log = 'true';
// change to 'false' to remove logging statements from you app.
// or (better) remove all logger statements from your code.
var log = 'true';
//var log = 'false';
/*
* the logger functionality is a attempt to recreate some of the console functions of
* fire bug for IE, the browser where you need js debugging tools the most. *
* to use it you replace console.log(msg) with logger(msg), this sends the msg to the console or
* it creates an ul to receive your (LIst of) messages...
*/
/*
* works in safari 2, opera 9, camino, webkit, ie 6 and firefox 2 (with or without firebug).
*/
function logger (msg){
if (log == 'true'){
// first we need to do some browser sniffing, look below for the explanation.
var b = navigator.userAgent.toLowerCase();
safari = /webkit/.test(b);
/*
we only sniff what we need...
opera = /opera/.test(b);
msie = /msie/.test(b) && !/opera/.test(b);
mozilla = /mozilla/.test(b) && !/(compatible|webkit)/.test(b);
*/
// bummer, safari seems to think that it has a console, so we make sure that it goes through.
if (window.console && !safari){
console.log(msg);
}
else {
if(!document.getElementById('logger')){
var ul = document.createElement('ul');
ul.id = 'logger';
document.getElementsByTagName('body')[0].appendChild(ul);
}
var ul = document.getElementById('logger');
var li = document.createElement('li');
ul.insertBefore(li,ul.firstChild);
li.innerHTML = msg;
}
}
}

I think that it is a nice solution to a real problem, if you want see my solution here. If you want to try other people's solutions, go and seek googles advice. Something that I should have done before writing my own stuff, but at least it helps me understand javascript a bit better. Something that is always good I think.

My advice to you is, either use my solution (and if you do, please let me know, I will be proud) or go and use faux console by Christian Heilman's. I think his is better javascript, as is to be expected...

The downside is that he wrote it to be included as a seperate piece of javascript and it still needs to have all of the console.log statements removed for the live code. Where as in my logger, all you have to do is change var log == 'true' to false to go live. I think that this is a strong point, in my situation where I deliver stuff to be tested in two day cycles, as it goes faster.