To use web fonts with wide browser support, we need the font files in .woff
and .woff2
format. Who does not care about Internet Explorer, Safari on Mac OS before Sierra, and a few mobile browsers can choose only .woff2
(there are tables with the browser support of the two formats on Can I use).
In this post, I show how to use the command line tool Glyphhanger to convert .ttf
files to .woff
and .woff2
and subset fonts to remove unused characters.
Update from July 22, 2018: Today I tried to install Glyphhanger and got an error that Chromium could not be downloaded. I found a fix for that in a GitHub issue and updated the post accordingly.
Why all the effort? There are services like Google Fonts or Typekit...
That is right. But if you use fonts via third-party services, user information (at least the IP address) are sent to this service, and that could be problematic with the upcoming GDPR.
Loading fonts locally from the web server is the safer variant.
What is Glyphhanger?
The project’s GitHub repo describes it as »web font utility belt«: it comes with various features that make working with web fonts easier. In the blog post »It’s Dangerous to Go Stallone. Take Glyphhanger«, Zach Leatherman introduces the tool that he created for the Filament Group.
Glyphhanger’s features in short:
- creating WOFF/WOFF2 files from
.ttf
. - subsetting fonts
- by specifying certain Unicode characters(ranges).
- by specifying one or more URL(s) from which the characters of the content are used as subsetting value. For that, there is also a crawler feature, so that linked pages of the website are also analyzed. Besides that, it is possible to provide a
font-family
value, to only get the characters that are inside of elements with that rule. Via a whitelist, you can specify characters that should be part of the subset in any case.
- convert a string to Unicode ranges.
- convert Unicode ranges to a string.
- CSS rules for using the subset.
Installation of Glyphhanger
Preliminary note: I installed it on Windows 10 with the Windows Subsystem for Linux. For the installation of fontTools (if I remember correctly) it was necessary to run Bash on Ubuntu on Windows as administrator.
To install Glyphhanger, run the following command (using --unsafe-perm=true --allow-root
was necessary for me with Ubuntu on Windows 10. Without it, I got an error that Chromium cannot be downloaded):
npm install -g glyphhanger --unsafe-perm=true --allow-root
Code language: Bash (bash)
To use the subsetting feature, you need the Python library fontTools, which can be installed with the following commands from the readme of the Glyphhanger project:
pip install fonttools
# Additional installation for --flavor=woff2
git clone https://github.com/google/brotli
cd brotli
python setup.py install
# Additional installation for --flavor=woff --with-zopfli
git clone https://github.com/anthrotype/py-zopfli
cd py-zopfli
git submodule update --init --recursive
python setup.py install
Code language: Bash (bash)
After that, Glyphhanger is ready to use.
Converting .ttf
files to .woff
and .woff2
First a note: the font license must, of course, allow the font to be used as a web font, be converted and modified (subsetting). The font license should present in the downloaded folder.
If you downloaded such a font, for example, from Google Fonts, switch to the command line and navigate to the folder with the font files. To convert them to WOFF and WOFF2 files without subsetting, the following command is enough:
Code language: Bash (bash)glyphhanger --formats=woff2,woff --subset=*.ttf
You should get back messages from the command line while the tool is working, like the following:
Code language: Bash (bash)Subsetting NotoSans-Black.ttf to NotoSans-Black-subset.woff2 (was 458.75 KB, now 162.26 KB)
Depending on the number of font files (and probably the size of the individual files), this may take some time. Afterward, you have files, which you can integrate via the @font-face
rule.
Useful for that: besides the new font files, you will notice CSS files, that contain examples of the rules to load the fonts:
@font-face {
src: url(NotoSans-Black-subset.woff2) format("woff2"), url(NotoSans-Black-subset.woff) format("woff");
}
Code language: CSS (css)
Font subsetting
Now the subsetting of fonts, the removal of unused characters from the font, to make the files smaller. Glyphhanger brings with --US_ASCII
and --LATIN
two presets for the subsetting. For my conversion from Google Fonts to self-hosted fonts, I used another solution.
The Google Fonts API URL for Noto Sans, for example, looks like this, when only loading the regular style: fonts.googleapis.com/css?family=Noto+Sans:400.
Accessing this URL will return several @font-face
rules for various character sets, including the specific unicode-range
details (with that, supporting browsers will only download the font file if needed). I used the values of unicode-range
for the --whitelist
parameter of Glyphhanger and created one subset after the other for the different character sets.
The command for creating the cyrillic-ext subset of Noto Sans, for example, looks like that:
glyphhanger --formats=woff2,woff --subset=*.ttf --whitelist="U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F"
Code language: Bash (bash)
I used the @font-face
rules from the Google API, modified the url()
values, added the url()
of the WOFF file, and used the unicode-range
values from the Glyphhanger CSS files (those are shortened by (hopefully) unnecessary characters, for example, U+0460-052F
becomes U+460-52F
).
And with that, we now have optimized font files for loading from the website’s server. Like said, the tool comes with various other options, like using the characters from a Website for the subsetting – that could be handy, for example, if it is a static website, that will not have content changes in the foreseeable future.