QR Code contains TinyURL of this article.Enhanced Typography With Unicode-Range

desk adorned with items related to or illustrating typography and type-setting

From Humble Beginnings…

Way back in 2008, Dan Cederholm advised designers to “Use the Best Available Ampersand” in their type. Cederholm quoted from Robert Bringhurst’s seminal work, “The Elements of Typographic Style:”

“Since the ampersand is more often used in display work than in ordinary text, the more creative versions are often the more useful. There is rarely any reason not to borrow the italic ampersand for use with roman text.”

Cederholm went on to illustrate the ease with which we can accomplish this with a HTML <span> tag:

<span class="amp">&</span>

…and a sprinkling of CSS:

span.amp {
  font-family: Baskerville, Palatino, "Book Antiqua", serif;
  font-style: italic;
}

I’ve used Cederholm’s “Best Available Ampersand” method ever since, on just about every website I’ve had a hand in.

There is, however, a fly in the ointment. Consistent deployment might be difficult due to the requirement for additional markup. A CMS might prevent this from being practical for instance, or a content producer might forget to wrap her ampersands with the appropriate <span> tag…

Using “unicode-range

Fortunately, there is another way and it requires no additional markup as it is entirely CSS-driven:

/* The magic! */
@font-face {
  font-family: PrettyAmpersand;
  src: local(Didot), local(Baskerville), local(Palatino), local('Book Antiqua'), local(serif);
  unicode-range: U+26;
}
/* The target */
h1, h2, h3, h4, h5, h6 {
  font-family:  PrettyAmpersand, 'Helvetica Neue', Helvetica, Arial, sans-serif;
}

“Whoa, hold on there cowboy… that’s a lot more CSS than Cederholm’s diminutive solution. What the heck is going on here?”

Okay, I admit, it might look intimidating at first glance. But let’s break it down, then you won’t feel so bad about it.

The first thing we’re doing — The Magic! — creates a new font-family we’re calling PrettyAmpersand, for which we set the font stack as: Didot, Baskerville, Palatino, "Book Antiqua", serif. This works exactly as you’d expect from font-family, the browser uses the first available font in the list.

The trick is that we only specify a single code point for PrettyAmpersand: U+26,1 the Unicode character &.

So, when we add PrettyAmpersand to the font-family of our heading selector(s) — The target — the only glyph that will use the typeface is our friend, the ampersand. The remaining characters will use the next typeface in the selector’s font-family. In the case of the example given above, that would be Helvetica Neue.

the ampersand character in a selection of typefaces

“Terrific. You’ve sold me. I’ll start reworking my CSS right away.”

Not so fast buster. It isn’t that simple. As is almost always the case, some browsers just don’t play nicely with others.

Dealing with the Rebels

At this point, you’re probably shaking your head thinking, “bloody Internet Explorer again!”

But you’d be wrong. This time it isn’t MSIE that we have to accommodate. Believe it or not, it’s Firefox. At the time of writing, the Mozilla Foundation’s browser doesn’t handle unicode-range properly. Support is coming, real soon. But, in the meantime, Firefox is the edge case and we have to treat it accordingly.

As much as I hate using them, a CSS hack saves the day in this case:

/* Firefox only */
_:-moz-any-link, :root h1, h2, h3, h4, h5, h6 {
  font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
}

This removes PrettyAmpersand from the font stack for the selectors h1-h6, when the browser is Firefox. Obviously, due to the nature of CSS cascades, the above snippet should follow the earlier CSS, otherwise it won’t work.

It Needn’t Stop There

If you’re anything like me, once you start with a trick like this, you just can’t stop. The good news is, you don’t have to.

With this technique, you can substitute any character in one typeface with the same character in another. This opens up all sorts of possibilities. For example, I am fond of non-lining numerical glyphs and I particularly like those of the Georgia typeface. With unicode-range I can enjoy Georgia’s numerical glyphs regardless of the font-stack I am using for other characters:

@font-face {
  font-family: Digits;
  src: local(Georgia), local(Garamond), local(Palatino), local('Book Antiqua');
  unicode-range: U+30-39;
}

Notice the slightly different syntax of the unicode-range value here: U+30-39. What we’re doing here is choosing a range of glyphs for this typeface, as opposed to the single one in the ampersand example. The Unicode code points U+0030-U+0039 represent, of course, the digits, 0-9.

Final Words

The ease with which we can change typefaces for individual or ranges of glyphs — without having to edit a single line of HTML markup — represents a typographic revolution when we first start using unicode-range. As with all “shiny things”, we should resist the temptation to go overboard with it. This technique can enhance our typography dramatically, but only when we use it judiciously.

  1. Find the Unicode value of any character with this online character converter↩︎