Combining fonts

I love the font Just Another Hand, I use it a lot in diagrams during my talks:

Here it is! Yay!

The thing is, I don't like the positioning of the hyphen & equals glyphs…

Cache-Control: max-age=3600

They look awkwardly positioned – they sit too high.

Thankfully CSS lets you merge fonts together, so I can create a single font family that's like Just Another Hand, except it takes the hyphen & equals glyphs from a different font, Architects Daughter:

Cache-Control: max-age=3600

How it works

The @font-face is defined as usual:

@font-face {
  font-family: 'Just Another Hand Fixed';
  font-style: normal;
  font-weight: 400;
  src: local('Just Another Hand'), local('JustAnotherHand-Regular'),
    url('https://fonts.gstatic.com/…woff2') format('woff2'), url('https://fonts.gstatic.com/…woff')
      format('woff');
}

But I added another @font-face of the same name for the hyphen & equals glyphs:

@font-face {
  font-family: 'Just Another Hand Fixed';
  src: local('Architects Daughter'), local('ArchitectsDaughter'),
    url('https://fonts.gstatic.com/l/…') format('woff2'), url('https://fonts.gstatic.com/l/…')
      format('woff');
  unicode-range: U+2d, U+3d;
}

The trick is in the unicode-range descriptor. It indicates that the src should only be used for the hyphen (U+2d) and equals (U+3d) code points. You can turn a unicode character into a code point using this snippet:

'='.codePointAt(0).toString(16); // "3d"

As an optimisation, I used Google fonts' text parameter to subset the "Architects Daughter" font, so it only contains the hyphen & equals glyphs. The woff2 version is 500 bytes – not bad!

And that's it. Now when I use:

.whatever {
  font-family: 'Just Another Hand Fixed';
}

…it uses a combination of both fonts!

Update: Do you need unicode-range?

A couple of people on Twitter and in the comments have suggested you don't need unicode-range, and you can just do:

/* Subsetted font */
@font-face {
  font-family: 'Just Another Hand Fixed';
  src: url('https://fonts.gstatic.com/l/…') format('woff2');
}

/* Main font */
@font-face {
  font-family: 'Just Another Hand Fixed';
  src: url('https://fonts.gstatic.com/…woff2') format('woff2');
}

This works visually, but it's worse in terms of performance.

In this case the browser downloads the subsetted font first, then it realises it doesn't have all the glyphs it needs, so it starts downloading the main font. The fonts download one after the other.

Live demo. Network waterfall.

Whereas with the unicode-range solution, the browser knows what it needs in advance, so it can download the fonts in parallel.

Live demo. Network waterfall.

Also, if you don't use one of the subsetted characters, the browser knows it doesn't need to download the font at all!

Live demo. Network waterfall.

View this page on GitHub

Comments powered by Disqus

Jake Archibald in a garden with a black cat

Hello, I'm Jake and that's me there. The one that isn't a cat. I'm a developer of sorts.

Elsewhere

Contact

Feel free to throw me an email, unless you're a recruiter, or someone trying to offer me 'sponsored content' for this site, in which case write your request on a piece of paper, and fling it out the window.