How to Use Cross Browser Web Fonts

Greetings, readers! This week I’m exploring web fonts, looking at the best way to use custom fonts on your site across browsers.

I’m going to start with some basic explanations so we all know what we’re talking about, then I’ll move on to some more advanced aspects in the following article.

Introduction

Using custom fonts on the Web (outside of the usual web-safe font set) was a complete pain for many years, with web designers having to resort to using weird text replacement techniques like image replacement or siFR, which proved to be hackish and inflexible.

But, no more! Since the CSS Fonts Module Level 3 gained widespread support across browsers, things have been much improved. Hell, web fonts even work as far back as IE5.5.

Let’s explore web fonts some more.

Basic web fonts syntax

At its core, the web fonts system relies on two things.

1. The @font-face rule

First you insert a block in your CSS, describing a web font you want to embed into your page. This information is all wrapped inside a @font-face block, like so:

@font-face {
	...
}

This should go at the top of your CSS: you want to make sure the font has been made available before you try to apply it to any text.

First, we include a font-family name, to identify the font in our CSS. This can be just about any name you like, as long you use it consistently (if the name has spaces in it, you need to include quotes around the name):

@font-face {
  font-family: Abril;
}

Note: Abril Fatface font can be found on Font Squirrel, a great source of free web fonts.

Next, you need to include the location of the font file you want to include on your page:

@font-face {
  font-family: 'Abril Fatface Regular';
  src: url("AbrilFatface-Regular.otf");
}

Note that you can include a series of locations in this line, separated by commas:

src: local('Abril Fatface Regular'), url("AbrilFatface-Regular.otf"), url("AbrilFatface-Regular.eot");

The browser goes through the choices in order, and finds the first one that works for it. In this case, we are asking the browser to first check whether the font is installed locally and use the local version if available (useful for potentially saving some bandwidth.)

Next, we include a reference to an Open Type format font, then lastly we include an Embedded Open Type version for old versions of IE to use (this is all they understand.)

Be aware that you can’t point to a font on a different domain, unless you use CORS (see an Apache-specific solution on David Walsh’s site)

That’s it for the essentials; our font should now be usable on our web page.

2. Standard font-family declaration

Now we’ve embedded the font into your page, applying it to some text is as simple as using the font-family declaration, just like we would normally:

h1 {
  font-size: 8em;
  font-family: 'Abril Fatface Regular', sans-serif;
}

See my first example for the above code in action.

Other @font-face options

There are a number of other options you can include in your @font-face rule:

@font-face {
  font-family: 'Abril Fatface';
  src: url("AbrilFatface.otf");
  font-weight: bold;
  font-style: italic;
  font-stretch: condensed;
  unicode-range: U+0026;
}

The font-* descriptors are for use when many different variants of a font are available in a single file. Here for example we are specifying that we’d like to use the bold, italic, condensed variant of the font, if it is available, rather than the browser downloading the whole lot.

The unicode-range descriptor specifies what glyphs from inside the font-file you want to use. U+0026 is the unicode for the ampersand (&), meaning that in this case only the ampersand would be downloaded from this font file for use on the page. This is a good technique for saving bandwidth when you only want to use a very specific character set in that font.

For more details, read http://www.w3.org/TR/css3-fonts/#font-prop-desc and http://www.w3.org/TR/css3-fonts/#unicode-range-desc

The cross browser reality

The reality of getting web fonts to work across browsers is a little different. Different browsers support a slightly different set of font formats, so you need to provide a set of alternatives.

  • Web Open Font Format (.woff): For all modern browsers
  • Embedded Open Type: For older versions of Internet Explorer (IE< =8)
  • SVG fonts: For older versions of iOS Safari (3.2-4.1)
  • Truetype fonts: For older versions of the default android browser

The @font-face rule in my second, cross browser example looks like this:

@font-face {
  font-family: 'abril_fatfaceregular';
  src: url('abrilfatface-regular-webfont.eot');
  src: url('abrilfatface-regular-webfont.eot?#iefix') format('embedded-opentype'),
       url('abrilfatface-regular-webfont.woff') format('woff'),
       url('abrilfatface-regular-webfont.ttf') format('truetype'),
       url('abrilfatface-regular-webfont.svg#abril_fatfaceregular') format('svg');
  font-weight: normal;
  font-style: normal;
}

This is pretty ugly, but fortunately you don’t need to generate it yourself: online resources like Font Squirrel have easy-to-use generators that take a font file, and generate all the alternative format files and CSS you need.

In the next part, we’ll get a little more advanced.

Note: If you really want to know why all this works, read Paul Irish’s Bulletproof @font-face syntax.

Chris Mills is a senior tech writer at Mozilla, where he writes docs and demos about open web apps, Firefox OS, and related subjects. He loves tinkering around with HTML, CSS, JavaScript and other web technologies, and gives occasional tech talks at conferences and universities. He used to work for Opera and W3C, and enjoys playing heavy metal drums and drinking good beer. He lives near Manchester, UK, with his good lady and three beautiful children.

Free Guide:

How to Choose the Right Charting Library for Your Application

How do you make sure that the charting library you choose has everything you need? Sign up to receive this detailed guide from FusionCharts, which explores all the factors you need to consider before making the decision.


  • http://www.dev-metal.com/ Chris

    I would like to add that since 2012 there’s a major bug in the webkit rendering engine used by Chrome and Opera that messes up rendering of most (!) fonts on Windows systems. The fonts simply look horrible, extremely pixelated etc. The Chrome dev team is working on it and there are some things developers can do to override this issue (but it will not work everywhere). I’ve written a very popular blog post on that: http://www.dev-metal.com/fix-ugly-font-rendering-google-chrome

  • http://webdesign-la-losangeles.com/ Sean

    Thanks for sharing the info with us. Cross platforms become a major task for the QA

  • pwrmacbob

    Newbie alert! What do you mean by: Be aware that you can’t point to a font on a different domain,

    • Cas Cornelissen

      According to the specification browsers should not allow for cross-domain fonts because of security reasons. At this moment, only Firefox and Internet Explorer implemented this correctly (meaning they don’t allow fonts from another domain), while Chrome, Safari and Opera all implemented it incorrectly (meaning they do allow it).

      More on why it’s not possible in Firefox can be found here: http://www.red-team-design.com/firefox-doesnt-allow-cross-domain-fonts-by-default

  • tomByrer

    Chrome (& I assume Opera) now use Blink, instead of WebKit. But seems your testing is post-Blink…

Learn JavaScript for free!
Free course: Introduction to JavaScript

Yours when you take up a free 14-day SitePoint Premium trial.