Font-weight is still broken in all but one browser

The CSS 1 font-weight property is used to display text with a Bold or Regular weight. This is achieved using font-weight:bold and font-weight:normal. So much so CSS 101. But there’s more to the lives of many typefaces than just bold and regular. There’s Ultralight, Extralight, Light, Thin, Medium, Book, Semibold, Demibold, Extra-bold, Heavy, Black, Extra-black, Ultra-black, and more besides.

Since its inception in 1996, CSS has provided a way of displaying these other weights through use a numerical scale with the font-weight property. This is still almost entirely broken in every current browser except Firefox 3 on Mac.

How it should work

As well as the normal and bold keywords, font-weight also takes nine numerical values of 100, 200, through to 900. These numbers span the scale from Ultra-light to Ultra-black, with normal defined as 400 and bold defined as 700. So to specify a Light weight you would write font-weight:200. Here’s a rough guide matching the numeric scale to common weight terms:

100Thin, Hairline, Ultra-light, Extra-light
400Regular, Normal, Plain, Roman, Standard
600Semi-bold, Demi-bold
800Heavy, Black, Extra-bold
900Ultra-black, Extra-black, Ultra-bold, Heavy-black, Fat, Poster

The numerical scale only loosely matches weight names as there’s no official definition of the terms – it’s entirely down to the typeface publisher whether a font be called Heavy or Black, or whether the font should be Extra-light as opposed to Ultra-light, so you may have to play around a bit.

What actually happens

I created a test case using Myriad Pro, as it has plenty of weights to play with; in my case I have Light, Regular, Semibold, Bold and Black installed. If you don’t have Myriad Pro installed, you’ll just see a monospaced font, but feel free to download and edit the text case file, and play around with another typeface. Incidentally I used the exact same PostScript-flavoured OpenType files for both Mac and Windows testing. The markup I used in the test case is roughly this:

p { font-family:"Myriad Pro" }
#one { font-weight:100 }
#two { font-weight:200 } ...
#nine {font-weight:900 }

<p id="one">100 why pangolins dream of quiche</p>
<p id="two">200 why pangolins dream of quiche</p> ...
<p id="nine">900 why pangolins dream of quiche</p>

Firefox 3 on Mac renders the test case as follows:

Screenshot for Firefox 3/Mac
Firefox 3/Mac: renders correctly

As you can see 100, 200 & 300 are rendered using the Light weight, 400 & 500 use the Regular weight, 600 is rendered in Semibold, 700 in Bold, and 800 & 900 are rendered using Black. This is the correct behaviour.

However Safari 3.2, Opera 10.00 Alpha, Firefox 3.0 on Windows, and Internet Explorer 8 Beta 2 all get this wrong in the similar, but subtly different ways.

Screenshot for Safari
Safari 3.2: 100–500 rendered in Regular, 600–900 in Semibold
Screenshot for Opera 10
Opera 10 Alpha: 100–500 rendered in Regular, 600–900 in Bold
Screenshot for Firefox 3/Win
Firefox 3/Win: 100–500 rendered in Regular, 600–900 in Semibold
Screenshot for <abbr class='c2sc'>IE8</abbr>
IE8 Beta 2: 100–500 rendered in Regular, 600 in Bold, 700–900 in Semibold

For the most part these browsers partially support the numerical scale, but only for two weights; Regular and either Bold or Semibold.

A workaround

There is a workaround. Following on the heels of Guillermo Esteves, it involves the clever addition of some font-families. As well as the font’s family name – Myriad Pro in the test case – each installed font weight has two other names: the screen name, eg. Myriad Pro Light and the PostScript name, eg. MyriadPro-Light (to find these names, use a font management tool such as FontExplorer X and click info for the font). To get Opera, IE8, Firefox 2 and Firefox 3/Win to render an alternative weight, you need to specify the screen name, so the test case would need to be modified as follows:

#one {
font-family:"Myriad Pro Light", "Myriad Pro"; }

However this doesn’t work in Safari, which needs the PostScript name. So your styles need to be further modified, as in the modified test case:

#one {
font-family:"MyriadPro-Light", "Myriad Pro Light",
"Myriad Pro"; }

There are distinct downsides to this workaround. Obviously the first is that you need to specify at least three font families just to change the weight. But the main problem is that font-weight will no longer work (apart from in Firefox 3/Mac) as the font-family you are now specifying only contains the one weight. So if you need an Bold word within a Light weight paragraph, you’ll have to specify the font-family as well as the font-weight. Not very practical.

Frankly it’s really depressing that this bug is still present after 12 years, and regardless of success or otherwise in Acid tests, these browsers cannot truly say they support even CSS 1 fully or correctly. I hope we see fixes soon (apparantly already done in WebKit). I know fonts are a tricky subject in operating systems, but if it can be done in Firefox 3/Mac then surely other browsers can quickly follow.