There are four modern font formats:
- TrueType (
.ttf
extension) - OpenType with CFF outlines (
.otf
extension) - WOFF (web font,
.woff
extension) - WOFF2 (web font,
.woff2
extension)
Although only WOFF, which stands for “Web Open Font Format”, mentions “web”, all of them can be used on the web.
Which File Format to Choose
WOFF format has the same browser support as the TrueType and CFF formats, so I’d say you must use at least WOFF when serving font files to your users.
WOFF2 has slightly less support across browsers, but we can safely assume that this format has been supported in all major browsers since at least Sep 17, 2018 (see Safari). The difference in support is negligible — only about half a percentage point less.
I encourage you to always go with WOFF2 unless you’re developing for Internet Explorer, in which case add fallbacks for WOFF. ttf
and otf
formats are unnecessary.
If possible, use variable fonts, as they combine multiple weights into one file.
Optimizing
Following Optimizing Web Assets, Part 1, General Ideas, there are four techniques to optimizing web assets, all of them are applicable to font files to some extent.
Minify
It is possible to minify font files by removing unused glyphs from those fonts. For example, if you need font A just for numbers, you can leave only digits from 0-9 and accompanying symbols like .
, ,
, etc. Tools like FontForge can help with that, although it doesn’t work well with variable fonts.
Usually, we want to use as few fonts as possible, but it’s inevitable to use more of them as your website grows with multiple language support. Some fonts like Google’s Noto Sans provide standalone files for different locales.
In the case of fonts which have multilingual support and are contained in a single file, you can refer to the Unicode Character Code Charts, use FontForge to extract glyphs into separate files, providing them with different filenames.
Compress
WOFF and WOFF2 have built-in compression, so when (if) converting fonts from ttf
or otf
, those files will already be compressed, so you don’t need to do anything.
Convert
I think it’s best to work with assets in their original form, or with the source, as developers do it with code. Therefore, I encourage you to minify your fonts in their source formats.
Regardless of whether you’ve made the font files smaller or not, if they’re not in WOFF format, you need to convert them. There is a handy CLI tool by Google to convert fonts to WOFF2: woff2. After building and/or installing it, it’s pretty easy to convert fonts now:
for filename in *.ttf; do
woff2_compress $filename;
done;
Since it’s a single-argument command, it’s pretty easy to remember, use, and incorporate into your flow.
woff
and dewoff
CLI comes with FontForge on MacOS, and I don’t know of any other good tools.
for filename in *.ttf; do
woff $filename;
done;
Delay
As mentioned in the Minify section, there is a Unicode Character Code Charts. Developers can use these charts and CSS property unicode-range
inside @font-face
to load specific font files when specified symbols are rendered on a web page.
E.g., Simplified Chinese (CJK Unified Ideographs (Han)) has unicode range of U+4E00
through U+9FFF
. To load font file for Chinese symbols, developers then declare @font-face
like this:
@font-face {
font-display: swap;
font-family: "Chinese Font";
src: url("/path/to/font.file");
font-weight: 300 900; /* if variable font */
font-weight: 300; /* if not variable font */
unicode-range: U+4E00-9FFF;
}
If there are multiple ranges of glyphs, such as in Traditional Chinese, developers can declare unicode-range
as a comma-separated list of ranges:
@font-face {
/* ... */
unicode-range:
U+4E00-9FFF, U+3400-4DBF, U+20000-2A6DF, U+2A700-2B739,
U+2B740-2B81D, U+2B820-2CEA1, U+2CEB0-2EBE0, U+30000-3134A,
U+31350-323AF, U+2EBF0-2EE5D, U+F900-FAFF, U+2F800-2FA1F,
U+2F00-2FDF, U+2E80-2EFF, U+31C0-31EF;
/* ... */
}