Problems loading local fonts with font-family
Posted on by Steve Workman About 5 min reading time
I'm investigating a problem with loading locally installed fonts in Windows 7. It's a weird one this, and it only seems to affect Firefox and IE9/10, or, those browsers that use DirectWrite.
The problem
This image shows the beautiful Univers font in four different browsers. Each of them are rendering the following CSS:
#univers55, #univers55bold, #univers45, #univers45bold { font-size:3em;}
#univers55 { font-family:"Univers 55", serif; }
#univers55bold { font-family: "Univers 55", serif; font-weight:bold; }
#univers45 { font-family: "Univers 45 Light", serif; }
#univers45bold { font-family: "Univers 45 Light", serif; font-weight:bold; }
Now, Univers 45 is a light-weight font, an should be a good 10 points lighter than Univers 55, you can see this in Chrome and IE8 (top-left and bottom right). In Firefox and IE10, Univers 45 looks heavier than Univers 55, and the bold version actually appears to be the same size. That just isn't right. So I called for reinforcements: step up Paul Rouget (Mozilla) and Martin Beeby (Microsoft).
Further investigation
I raised a bug against Firefox core with a test case on jsfiddle and got some good responses. Martin and Paul both asked:
@steveworkman @paulrouget could you include the font-face code in the fiddle for Univers 55 and Univers 45 Light
So, they thought it was something to do with the way I was including the font in the CSS. So, let's put it in and see what happens:
The rendering appears to have corrected itself. Univers 45 and 55 are now properly weighted in Chrome, IE10 and Firefox. So, what happened? Well, Jonathan Kew sheds a little light on the problem:
Note that the @font-face rules shown in your second image are incorrect (e.g. 'src: "Univers 55"' is invalid; did you mean "src: local('Univers 55')"?), and as a result you're not getting Univers at all in some of those examples, you're getting fallback to the default sans-serif font, probably Arial. Look at the shape of the "5", for example.
Also note that under the DirectWrite model, font families are organized differently from the old GDI model. Family names like "Univers 45 Light" are not generally used; instead, all the faces belong to a single family, with distinct font-weight values. (But I haven't examined the Univers family to see exactly how they're organized.)
So, yes, a little stumble over the "local('font-name');" issue, but otherwise it appears to be fine. The second part where he mentions that in Windows 7, font families are organised differently, and so may be under a different name intrigued me. So, I took a look:
So, this is where it goes a bit fuzzy. I can address the "Univers 45 Light" font directly through font-face, but I can't access the "Univers 55 Normal" font, though I can access the whole font family by looking for "Univers 55". That doesn't feel right to me, and needs more investigation. Still, I can at least get it to render the font when using font-face. So, is that it? Bug closed?
Why can't I just use font-family?
This is the question that I want answering, and Martin has kindly volunteered to look into. Loading a local font through font-family should work in exactly the same way as @font-face and src: local(); - but in Firefox and IE 9/10 it's not.
So, web community, do you know why this doesn't work? Can you make it work with the test case? Please help! Leave a comment, send me a tweet or update the test case and make it work!
UPDATE 1st November 2011:
Jonathan Kew has responded again with some more words of wisdom for me:
The @font-face and non-@font-face cases there aren't comparable. When you say
font-family: "Univers 55";
without the use of @font-face, you're requesting that _font family_, which may have multiple faces with different weights. What you'll get when you use font-weight:bold along with this depends which faces have been grouped under that family name - which may well differ between GDI and DirectWrite environments. And if there's no "bold" face in the family, then the browser will artificially "embolden" the text. (You can tell exactly which font is really being displayed using the "font-info" add-on, btw.) I suspect you might get a true bolder face in one case and synthetic bold in the other, but that depends very much on the structure of the font families you're using.
In the @font-face case, you're defining your own font families (independently of how the OS or the font designer organized things), and your CSS only assigns them a single (normal-weight) face each, which means that when your styles ask for font-weight:bold, you should be getting synthetic emboldening rather than a real face with a heavier weight.
To see what faces are supposed to be available within each family, look in the Windows Fonts folder - IIRC, this should reflect the DirectWrite organization of the fonts. Do you see separate "Univers 45" and "Univers 55" families? What faces exist in each?
So, I looked back at the spec and re-engineered the @font-face CSS, and the non-font-face CSS. The non-font-face CSS was definitely wrong, so I updated that, but the @font-face CSS still wasn't working. I looked at the font libraries as they are in Windows, and identified the following named structure:
Univers 45
Univers 45 Light
Univers 45 Light Oblique
Univers 55
Univers 55 Black
Univers 55 Normal
Univers 55 Oblique
Given the advice Jonathan gave me, the correct font-family should be "Univers 45" and "Univers 55", and the correct fonts for @font-face should be "Univers 45 Light" and "Univers 55 Normal". That gave the following results in Firefox and IE10
IE is finding the correct font, but Firefox isn't and is falling back to the serif font. I used the font finder plugin to look at which fonts were being used on the page, and the answer surprised me. When loading the Univers 55 font-family, the normal weight font is titled "Univers 55 Roman", instead of "Univers 55 Normal", and the bold version is "Univers 75 Black", instead of "Univers 55 Black".
So, I took a look at the system file properties for the font, and lo-and-behold, the detailed properties were different to the name of the font:
I quickly looked to see if Firefox was looking for the title property instead of the file name, and I was right. If you've got the Univers font you can see the jsFiddle test case for this, otherwise, the final result is below:
The @font-face code goes like this:
@font-face {
font-family: MyUnivers55;
src: local('Univers 55 Roman'), local('Univers 55 Normal');
font-weight:normal;
}
@font-face {
font-family: MyUnivers55;
src: local('Univers 75 Black'), local('Univers 55 Black');
font-weight:bold;
}
@font-face {
font-family: MyUnivers45;
src: local('Univers 45 Light');
font-weight:normal;
}
It looks to me like IE and Firefox use different properties to identify fonts under Windows 7: IE looks at the name in the file system and Firefox looks at the Title attribute of the file.
Amazingly, it looks like the spec doesn't care which one is right, and advises you to include both as different platforms use different naming conventions. What surprises me is that two browsers look for a different name on the same platform, as this could cause naming clashes; the Univers 55 Black is titled Univers 75 Black - so if there was also a Univers 75 Black titled Univers 85 Black, browsers are going to retrieve the wrong font.
So, Microsoft, Mozilla, please sort it out :-) Who is right?