Zach’s ugly mug (his face) Zach Leatherman

Unicode Range Interchange

March 04, 2021

Last week an issue came in from polarbirke’s Avatarpolarbirke on Twitter that the web font we use for our titles was overly aggressively subset! Oh no!

I thought it might be instructive to go through how I would go about adding a character or set of characters to an existing subset web font. I’ll be using a new unicode-range calculator tool I shipped this week called Unicode Range Interchange.

Behind the scenes, Unicode Range Interchange uses an awesome library from bram_stein’s AvatarBram Stein called characterset. I’ve used it for many web font things over the years—super useful.

  1. Find the existing unicode-range value in your CSS @font-face block. uses BenchNine and is subset with unicode-range: U+20-7E,U+2014,U+2019.
  2. Plug this into the first text input field on Unicode Range Interchange. It shows you the characters and the size of the set (in this case, 97 characters).
  3. Leave the Union operator selected. We want to combine our unicode-range with the new characters we’re adding.
  4. Type the characters you’d like to add into the next text field. You don’t need to use a unicode-range if you don’t want, although it is supported.
  5. Optionally you can use glyphhanger to parse a page to find the unicode-range of all the characters in use on that page. It can even search for nodes using a specific font-family! I used glyphhanger http://localhost:8080/authors/ --family='BenchNine' to find all the characters used by the BenchNine font-family on my locally running site. glyphhanger returned U+20,U+21,U+23,U+26,U+2A,U+2C-2E,U+30-3B,U+41-57,U+59,U+5A,U+5F,U+61-7B,U+7D,U+E9,U+F4,U+F6,U+F8,U+15A,U+200B,U+2014,U+2026 (82 characters). I put this value into the second input field on Unicode Range Interchange.
  6. The output will now show a new unicode-range, combining and simplifying the first two! My result was U+20-7E,U+E9,U+F4,U+F6,U+F8,U+15A,U+200B,U+2014,U+2019,U+2026 (104 characters)

It looked like this:

A preview of the Unicode Range Interchange page, showing the instructions described in this post.

Then you can use glyphhanger to modify your web font files with the new unicode-range value.

glyphhanger --whitelist=U+20-7E,U+E9,U+F4,U+F6,U+F8,U+15A,U+200B,U+2014,U+2019,U+2026 --formats=woff2 --subset=BenchNine-Bold.ttf

If you’d like you can also use pyftsubset (which glyphhanger uses behind the scenes):

pyftsubset "BenchNine-Bold.ttf" --output-file="BenchNine-Bold-subset.woff2" --flavor=woff2 --unicodes=U+20-7E,U+E9,U+F4,U+F6,U+F8,U+15A,U+200B,U+2014,U+2019,U+2026

Now you have a new WOFF2 web font file, with a few new characters added (and importantly, no characters removed).

And don’t be like me and forget to update your CSS with the new unicode-range value.

< Newer
Queue Code—“Live” Code without Errors
Older >
This Web Site is a Tech Talk

Zach Leatherman IndieWeb Avatar for a builder for the web at IndieWeb Avatar for He is the creator and maintainer of IndieWeb Avatar for https://www.11ty.devEleventy (11ty), an award-winning open source site generator. At one point he became entirely too fixated on web fonts. He has given 81 talks in nine different countries at events like Beyond Tellerrand, Smashing Conference, Jamstack Conf, CSSConf, and The White House. Formerly part of Netlify, Filament Group, NEJS CONF, and NebraskaJS. Learn more about Zach »


Khalid ✨Fresh Frontend LinksIndieWeb Avatar for https://cloudfour.comIndieWeb Avatar for https://mailsgun.ruIndieWeb Avatar for https://news.bbspace.topnic


Chris Burnellrm -rf fascismNikita VoloboevPeter AntoniusMax BöckⒸⓐⓡⓛⓞⓢ Ⓡⓞⓓⓡⓘⓖⓤⓔⓢyour favorite JackieAshur CabreraSøren Birkemeyer 🦊
  1. Søren Birkemeyer 🦊


    Look at those sparkling characters! 😍 Thanks for the fix and the explainer! If only it were that easy to get an ø on my passport.

  2. Zach Leatherman


    do passports use web fonts

  3. Zach Leatherman


    Next step is to have this setup per typeface and font file 🎉

  4. Nicolas Hoizey


    Indeed! I'm starting working on another personal site that will have fonts, so it will be a required step. 👍

  5. Søren Birkemeyer 🦊


    Good man, that Zach person. We‘ve truly entered a new era, considering I still remember typing „o“, backtracking and overlaying it with a „/“ on the typewriter I used for high school papers.

  6. Andy Davies

    Andy Davies

    @zachleat @sil Yeh, I just independently found And it does exactly what I need for now Thanks for making it Unicode Range Interchange

Shamelessly plug your related post

These are webmentions via the IndieWeb and

Sharing on social media?

This is what will show up when you share this post on Social Media:

How did you do this? I automated my Open Graph images. (Peer behind the curtain at the test page)