Whenever you want to use custom fonts on the web, you need webfonts. And whenever you make webfonts, file size will be your main concern. Learn how to properly create WOFF and WOFF2 fonts, plus some neat tips as a bonus.
Needless to say, the smaller the better. A well-subsetted single-script webfont should clock in below 20K, and therefore, load fast.
I told you above that file size is the primary issue. Number two on the list will be browser support. Unfortunately, not every web browser can handle every webfont file format. Glyphs can produce four kinds of webfonts: WOFF, WOFF2, and plain OpenType fonts (TTF/OTF). Here is a quick overview:
- WOFF: Web Open Font Format. Longest supported format, necessary for legacy browsers. Chrome 5, Firefox 3.6, IE9, Edge, Safari 5.1, Opera 11.1, Android WebKit 4.4, and all respective later versions. More info about WOFF support.
- WOFF2: Web Open Font Format 2. Best compression, and wide support in current browsers. Chrome 36, Firefox 39, Safari 10 (macOS 10.13 High Sierra and iOS 11 and later only), Edge 14, Opera 23, and all current Android browsers; not supported on Opera Mini and BlackBerry. More info about WOFF2 support.
- Plain OpenType: OTF and TTF. Fallback format for very old browser versions. that did not support WOFF back then. Chrome 4 (0%), Safari 3.2–5.0 (macOS and iOS, 0%), Firefox 3.5 (0.01%), Opera 10.1–11.0 (0%), Android Browser 2.2 (0%). More info about TTF support.
You can safely ignore Plain OpenType. Yes, it does not hurt to implement them, but hey. As of this writing, not even 0.02% of web browsing may be done in browsers that necessitate these formats. Probably even less by the time you are reading this. In other words, focus on WOFF and WOFF2. Now, read on.
Sure enough, to export the fonts you have set up in File > Font Info > Exports, you simply choose File > Export (Cmd-E) and pick the OTF option in the top row. You are presented with this dialog sheet:
You basically need to make three decisions:
Outline flavour: OpenType/CFF vs. TrueType. The radio buttons determine in which outline format the fonts will be exported. TrueType-based fonts use components for keeping the filesize small, PS-based fonts use a technology called subroutinisation. Complex outlines cannot be subroutinised. Windows has performance problems with complex PS outlines, and sometimes you will see a difference in screen rendering, especially with hinting (see following point). You may need to try both, compare file sizes and rendering quality, and then decide.
File format: .ttf/.otf, .woff, .woff2. The file formats in which the files will be exported, as discussed above. The option .ttf/.otf (depending on the outline flavour) are what is referred to as the Plain variant, in case you wondered. You want .woff and .woff2.
Autohinting: if activated, ttfAutohint will be used on TT-flavoured fonts, and Adobe’s autohinting algorithm will be applied to PS/CFF-falvoured fonts, respectively. Complex fonts cannot be hinted.
Remove Overlap: always on for shipping fonts, and for testing screen rendering. Only consider turning it off in order to speed up the export process if you are testing for character set and OpenType features. See Pro Tip below.
And, well yes, the fourth decision, the Export Destination, lets you preset a n export folder, which spares you the extra save dialog that follows otherwise. That can significantly speed up your export process, especially if you find yourself reexporting a lot in your quest to squeeze another kilobyte out of your WOFFs. All you need to export again is to press Cmd-E and hit the Return key.
You can use the following parameters either in File > Font Info > Exports, or in a .glyphsproject file.
- Webfont Formats: This allows you to specify which formats will be exported of the instance in question. You must use this parameter if you are outsourcing webfont production into a .glyphsproject file. Always Pick WOFF and WOFF2 unless you know what you are doing. And maybe throw in legacy EOT and Plain TTF files.
- Webfont Only: Will fiddle with the tables inside the font in a way so that a rogue user will have difficulties reverse-engineering the OTF or TTF from the webfont. However, we do not recommend this. Use this parameter only if your client insists on this as an additional safety precaution.
- Remove post names for webfonts: Removes glyph names in the webfont export, resulting in slightly smaller file sizes. may make a difference if you have a lot of dot-suffixed glyphs (for OT features), causing long production names.
- Save as TrueType: Forces the TrueType option of the export dialog.
- Autohint: Forces the Autohinting option of the export dialog.
But wait, there are more custom parameters available for your webfont geekery. Read on.
Subsetting refers to the removal of (unnecessary) glyphs from the font, thereby making the font a little smaller in terms of filesize. There are basically two mutually exclusive ways to achieve subsetting in Glyphs: either specifying which glyphs you want to keep, or which glyphs you want to get rid of. In both cases you take care of the subsetting with a custom parameter in File > Font Info > Font, or File > Font Info > Exports, or in a .glyphsproject file:
- Remove Glyphs: You supply a list of glyph names to specify which glyphs will not make it into the exported webfont. Simply type out all glyph names, separated by newlines.
- Keep Glyphs: same as above, except this time you specify which glyphs you want to export. All other glyphs in the font not mentioned in this parameter will not be exported.
In both cases, you can speed up things by using the Copy Glyph Names > One per Line command from the context menu in the Font tab (Cmd-Opt-1). And then paste your clipboard content into the parameter value. The only glyphs you cannot remove are
And you can use the asterisk (*) as a wildcard, both at the beginning and end of a word. E.g., you may want to write
ord* instead of spelling out
*.ss05 for all stylistic set 5 glyphs, or even
*.ss* for all stylistic sets.
Even better, there are also key wildcards available. They allow you to add complete categories, subcategories and even scripts to the list of glyphs to be removed (or kept). A key wildcard consists of the case-sensitive glyph info key (
subCategory), followed by an equals sign, which in turn is followed by an appropriate value for the key. Say you want to get rid of all Greek letters, all lowercase letters and all figures, so you add these lines to your Remove Glyphs parameter:
And you can combine the key wildcard with the asterisk. E.g., in order to delete all glyphs with Unicode values from
U+04FF, you would add this to the parameter value:
OK, now that we have the tools for subsetting in our hands, what do we get rid of? Here are a few inspirations:
- Small caps:
- Figure variants:
*.tf *.tosf *.osf *.lf
- Stylistic sets:
- Character variants:
- Very rare, deprecated, unused or untypable letters:
AEacute aeacute Aringacute aringacute IJ ij napostrophe Oslashacute oslashacute
- Localizations and compatibility glyphs:
Tcedilla tcedilla Ldot ldot
- Rare symbols:
lozenge paragraph currency florin logicalnot infinity integral product summation radical micro partialdiff perthousand registered trademark bar brokenbar dagger daggerdbl estimated apple
- Letters for languages that are not necessary on the website it is intended for. E.g., on that page dedicated to Dutch literature, you will very likely not need those extra glyphs that are only used in Esperanto,
Ccircumflex ccircumflex Hcircumflex hcircumflex Jcircumflex jcircumflex.
- Letters of scripts that are not needed for the purpose of the font. Bulgarian webpage? You will need Cyrillic, maybe a little Latin, but probably not the Greek parts of the font, so you go:
Anything else? Sure, but your mileage may vary. So, after export, always verify the glyph set and see if there is one more glyph you can take out. To do that, it is a good idea to export and test often. You can quickly open your font in apps like OTMaster or FontTableViewer, or on test pages like Wakamai Fondue or FontDrop, see further below for more info on those. Did an unnecessary glyph still make it through the limbus? It will not go unnoticed.
If you have done subsetting, and you export, you may end up with an error dialog like this:
The dialog reports an unknown glyph in the feature code. It mentions a glyph name (e.g.,
brevecomb and other combining accents in this example), and the exact spot: which line inside the font’s features (line 20 in this example), and which line inside which feature (line 2 in
ccmp in this case). What most likely caused the error is a glyph name that still appears in your feature code but points to a glyph that is removed in the process of subsetting. In other words, the feature code in File > Font Info > Features is not in sync with the glyph structure in the subsetted instance.
If the feature in question is an automatic feature, this should not have happened in the first place. But it can happen if you have some complex custom parameter stuff going on. In that case, you may need to force the automatic update, simply by adding this custom parameter to your instance, and activating its checkbox, of course:
- Update Features: force-refreshes all automatic OpenType feature code (including classes and prefixes) if enabled.
If, however, you have non-automated manual feature code, you may want to consider one of these parameters:
- Remove Prefixes: takes a list of prefix names and deletes them during export.
- Remove Classes: takes a list of OT class names (without the preceding at sign), and deletes those at export.
- Remove Features: takes a list of four-letter OT feature tags, and deletes the respective features at export.
- Replace Prefixes: supply the name of a prefix as it appears in the sidebar, followed by a semicolon, followed by new code, which is inserted at export time instead of the original code.
- Replace Classes: supply the name of an OT class (without the preceding at sign), followed by a semicolon, followed by new code, which is inserted at export time instead of the original code.
- Replace Features: supply the four-letter feature tag of a Feature, followed by a semicolon, followed by new code, which is inserted at export time instead of the original code.
More file size reduction
Experience shows that the most significant reductions are achieved by subsetting, but there are more ways to squeeze another kilobyte or two out of your WOFFs. To find out what causes the most weight gain in your webfont, see how big the tables are in your WOFF. The best way to do this is to download and install fonttools, and list all font table by running
ttx -l fontname.woff in Terminal. Or better, you type
ttx -l followed by a space, and then drag the WOFF into the Terminal window, which inserts its file path, then press Return. If everything went fine, you will get a list of tables similar to this:
tag checksum length offset
---- ---------- -------- --------
CFF 0x9C30A665 29398 2992
GDEF 0x3C093D1F 189 32392
GPOS 0x15445ACD 13356 32584
GSUB 0x42EA82BB 1429 45940
OS/2 0x68B4820A 78 1372
cmap 0x8F4E4BFE 1042 1928
head 0x12AB135E 52 292
hhea 0x066A05BF 32 1340
hmtx 0x1BC61668 994 344
maxp 0x02435000 6 284
name 0x76A3CF96 475 1452
post 0xFFB80032 19 2972
Look at the length column: You can tell that the table with the tag
CFF (Compact Font Format, with PS outlines) takes up the most space, closely followed by
GPOS (glyph positioning).
hmtx are directly influenced by the number of glyphs in the font, while
GSUB get their gravy from all OT features (including kerning) in your font.
CFF is also where the PostScript hinting info is stored.
Let’s take a look at a typical TT-based webfont:
tag checksum length offset
---- ---------- -------- --------
DSIG 0x00000001 8 14124
GDEF 0x01C701B8 28 384
GSUB 0x4C1A4D0D 492 412
OS/2 0x697CB056 76 904
cmap 0xEFD48A4D 628 980
cvt 0x0CE0037F 40 12208
fpgm 0x9E3611CA 1729 12248
gasp 0x00000010 8 12200
glyf 0xE8E7B58E 8718 1608
head 0x112593E0 53 10328
hhea 0x088C054F 32 10384
hmtx 0xDBC80FBB 336 10416
loca 0x668F76DC 216 10752
maxp 0x033E0F25 32 10968
name 0x6F5D0BBB 348 11000
post 0x55CEA4FD 852 11348
prep 0x6846C89C 143 13980
In TrueType fonts, outline info is stored in the
glyf table, typically the largest table in the font. TT hinting info is spread across
So, depending on where you count the most bytes, you can make an informed decision on which file reduction steps you want to take next. Here are a few suggestions.
Are you exporting TT-based webfonts and using the Autohint option? Add a TTFAutohint options parameter to your instance, and fine-tune where possible:
- Limit your hinting: ttfAutohint can be limited to a certain PPM size. Try to keep it as low as possible, only employ it for sizes where it really makes a difference. So, keep your Hinting Limit low, e.g. below 50, and employ a small Hint set range that encompasses only the most important PPM sizes, e.g. 12 to 32.
- Avoid extras such as Hint composites, Adjust subglyphs, Detailed info, and ttfa table. They are usually not needed, and can take up quite a bit of space.
- Activate No Autohint Info. It is not much, but hey.
If you are exporting CFF-based webfonts, perhaps only apply hinting to the glyphs you need most. Consider a custom parameter called Disable autohinting for glyphs and supply a list of glyph names that should be excluded from hinting.
If your font is for catering only or mainly to Apple hardware: Consider removing hinting altogether, or perhaps also supply an unhinted version that is delivered only to Apple devices. If your web admin knows how to do that, of course.
A lot of kerning will evaporate once the involved glyphs have been removed. But the kerning that is left may still be a burden on the file size.
Get rid of smallest kern pairs. Anything up to a certain threshold value can go. Depending on the design, that can be 5 or 10 units, for instance. In the mekkablue scripts you will find a Metrics > Delete Small Kerning Pairs that will help you with this task.
Needless to say, do this only with a copy of your font.
Consider a Remove Glyphs parameter for deleting combining accents—of course only if your font uses scripts that do not depend on them, e.g., Latin, Greek or Cyrillic. The lack of combining accents will prevent Glyphs from building the
mark (Mark Attachment) and
mkmk (Mark-to-Mark Attachment) features and therefore reduce the size of your GPOS table. You can achieve that by removing all
Be careful though, it may backfire: TT-based files may become larger because they cannot employ the combining accents as components in your diacritics anymore. So, always test, compare and verify. If the file size grows, instead of deleting the combining accents, consider a Remove Features parameter with:
CFF-based fonts should always slim down when you get rid of combining marks, because they do not use components in the first place.
For CFF-based WOFF and WOFF2 fonts, you can also try disabling subroutinisation. The compression used by WOFF and WOFF2 sometimes actually does work better. It is worth a try, so add the parameter Disable Subroutines to your instance, flick on its checkbox, then export and measure file size.
According to Miguel Sousa from Adobe, a font that is not tested is a broken font, and he is right. But how do you test a webfont? In browsers of course: Safari, Chrome and Firefox on the Mac, and in Chrome, Edge, and Firefox on Windows. And how do we do that, ‘test in browsers’? Well you have several options.
First of all, right after export, you can run Test > Webfont Test HTML from the mekkablue scripts, available through Window > Plugin Manager > Scripts. It will create an HTML file for the current file (.glyphs or .glyphsproject) inside the mostrecent folder into which you exported a webfont. And it will open that HTML for you straight away in your default browser. Then you can activate OT features, type your test text, and see your font in several sizes. It also provides sample CSS code.
Or you can drag your finished WOFFs into Viktor and Clemens Nübel’s fantastic FontDrop, which they developed for Monotype. Drag your WOFF in, get an overview of your complete font. Good for testing font info, hinting (with waterfalls) and glyph set. Heck, it even provides spacing indicators! Downside: it does not support WOFF2 yet.
Similar to this, you may want to use Roel Nieskens’ genius Wakamai Fondue test page. It is insanely great for testing OT features, and even provides sample HTML and CSS code for your copy-pasting pleasure.
And then there is the great Font Goggles app by Just van Rossum. It supports all kinds of font formats, including WOFF and WOFF2.
Simon Cozens’ Crowbar online tool for debugging shaping/layout issues supports webfonts too. Crowbar uses Harfbuzz to shape the text, and you can precisely see what happens during various stages of OT feature application.
Update 2019-07-30: corrected typos. (Thanks Nathalie.)
Update 2020-09-22: updated for Glyphs 3.
Update 2020-11-13: updated for Glyphs 3, added Font Goggles and Crowbar.
Update 2020-12-04: minor formatting changes, updates, fixed typos.
Update 2022-17-08: minor formatting changes.