Howto Use Custom Web Fonts

Robert Crowther Jan 2022
Last Modified: Feb 2023

Operating systems have a stock set of fonts that can be relied on. These date back to the beginning of CSS when, as far as I recall, Microsoft generously released a base set of fonts for use in CSS. These are the well‐known faces “Times New Roman, Georgia, Impact” and so forth. Aside from the use of “Comic Sans”, and ‘Impact’, which is a legendary font but I have never seen on the web, the Microsoft fonts are a useful list. And MicroSoft later added the amazing “Verdana”. The Open‐Source guys naturally did their own thing, released a set of ‘near’ fonts.

Everyone had a base to work from, but nobody was happy. Designers always want it all, and they wanted to muck about with fonts at will. But this is not a simple problem. Using a different font means uploading the new font to the browser—then you need to throw in the difficulties surrounding standards. Years later, CSS started to catch up. Nowadays, a designer can get a webpage to print in a font they want. And pages with different fonts are more common now. But usually on big sites. This is how do you do it.

Earthwork

Before we start,

What you need to know about font formats

Font construction, packaging, and licencing is a professional field. You can spend a life there, so I give warning, don’t get sucked in, This is all you need to know to get fonts into a website. In order of appearance,

Postscript fonts, Type 1

By Adobe circa 1985. One of several types of Postscript font, Type 1 used a reduced set of drawing operations and included hinting. The target usage was specific, computer display. Deprecated 2021–2023

TrueType

By Apple circa 1991. Outlines and sophisticated bitmapping

Opentype

By Microsoft 1996. Embraces many aspects of both Postscript Type 1 and TrueType fonts

Also, there are two compression standards. The Woff format is an OpenType or TrueType font file compressed and annotated,

Woff

2009. Supported by all major browsers

Woff2

2018. Advanced compression, supported by all modern major browsers

For web work, you mostly need TrueType fonts, preferably converted to Woff2.

Font variants/shapes

Perhaps you are accustomed to working with stock fonts, where everything is preloaded under one name and CSS can select variants/shapes. However you install and use. no such ease if you want to deliver your own fonts. Fonts often come in separate files, and you will need to download separate files for ‘Regular’, ‘Bold’, ‘Italic’, ‘ItalicBold’ and so forth.

Variants as different files

It makes sense to deliver variants in separate files because, for example, small‐caps is a distinctive variant which many will not need. That said, if you want small‐caps, then use CSS to generate small‐caps (see faux‐variants, below), you may get joyless results. Also, if you use variants from separate files, your CSS will need adapting. No longer can you use a simple CSS rule,

h3, h5 {
  font-variant: small-caps;
}

Nope. You need to load the variant, then make font‐family declarations for small‐caps declarations, like this,

@font-face {
  font-family: VollkornSC;
  src: url('/static/fonts/VollkornSC-1.woff2') format('woff2');
}
...


h3, h5 {
  font-family: "VollkorSC";
  font-variant: small-caps;
}

The regular rule is there so it will work for fallback fonts.

This can be a lot of work. If all you want is some fancy headlines, you’ll be ok. But to fully convert to a custom font needs a new CSS file.

Faux‐variants, and optimisation

If asked to deliver a font variant in a family, but no variant is available, browsers will try modifying the font themselves. Not what the font‐designer intended, not what the fussy web‐designer wants, and can look wrong.

That said, sometimes the result may be close enough. In which case, faux‐variants can be seen as a chance for optimisation. If, for example, the a faux‐Bold variation is good enough, you don’t need to convert the

font-weight: bold;

declarations in your CSS. And you don’t need to link or upload the xxxBold font file either. Which, given that a regular font alone can be 500k in size, could lead to a large increase in first‐landing page speed.

How to get custom fonts active

Two ways,

Upload a file to the website

If you want to do this, then you must be able to upload content to the server, and configure the URLs.

Pros,

Cons,

Use links through the web (cloud)

You can paste some HTML into the Head element of the page. The HTML will download the font to the user’s machine.

Pros,

Cons,

About speed

This mainly seems to depend on the font file size, rather than the delivery method. I found a standard variable font is maybe 300kB. You can get reduced sets down to 50kB. If you are serving multiple high‐res images, that’s nothing. But if you send text‐only/handmade‐CSS pages, a download of that size will swamp the response, becoming the critical factor by anything up to a second. The only fix is to make the file smaller.

About complexity

Beyond speed, know in advance that optimising fonts can be heavy work. You can pass hours with unfamiliar, one‐use software.

How to decide

I think the decision is pretty easy. For some people, they have no choice—with no control over the sever, they must use linked web uploads. That said, most people have enough control to use file upload. But do you want to? Do you want the maintenance hassle of server logons, file transfer, CSS reloading and cache tuning? If it’s any help, I saw somewhere that over 1 in 20 websites use Google’s cloud solution—that is stunning, especially for a relatively new technology. A tribute to Google’s delivery of this service. But there are good reasons for delivering your own font files so, if you are building sites from ground‐up, do not be put off.

How to weblink fonts from Google

I’m going to spend little time here, because it is so easy.

Go to Google Fonts. Pick a font. Select the families you are interested in. Go to the sidebar and select ‘embed’. It will give you HTML like,

<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Vollkorn&display=swap" rel="stylesheet">

Paste into your page header. Now you can declare CSS like,

 font-family: ''Vollkorn', ''Times New Roman', serif;

There’s a bit more to it than that, see above about variations, but hey, no registrations, logons, bizarre declarations, modules or contorted configuration. Snappy, huh?

How to prepare and serve font files

Oh, ok. This will be deeper, further, much further to go.

Decide a source of fonts

You can download from the web, or grab a font file.

Fonts from Google

Same source as for cloud downloads, but this time download a font. I do not know if Google fonts can be reduced for glyphs, everything I downloaded was full size.

Fonts from other sources

You can use font files from anywhere. You can copy font files out of your computer. Linux users have swathes of fonts available in the Larabie collections (‘graffiti’, ‘computer‐pixel’, no problem). If you are keen on typography, try rooting round the TeX universe. I’m suggesting these sources because fonts you find there will mostly come with open licences. Remember that some of these non‐tailored font sets will be massive, and you will need to cut them down.

Also consider the file format. Jump to ‘Convert a file…’.

Licensing

If you find a font file, are you allowed to use it? Some files will come with licence files, but not many. Those that don’t, try a web search, see if you can track down a licence. You want to know two things,

Some hints, fonts from the Google font site will be free. Fonts from Adobe, as far as I know, are free for web use, but not for commercial use. If you found the font in some software, or on your computer, the answers to these questions can be difficult to find.

Beyond, you will find organisations selling free‐licenced fonts. Of course, these organisations are providing a consistent platform for font delivery. Maybe.

How much do font files cost?

About £30. Usually. For the artistry, technicality, and work, I’d say that was good value.

(if necessary) Covert a font file to TrueType

TrueType is mostly what you aim at. But, especially if you find a font file in the wild, you may need to convert it. The way to do this is using FontForge (see below),

Open the file in FontForge. If you are ok using the commandline you can work directly—which avoids FontForge’s custom GUI,

fontforge /usr/share/texlive/texmf-dist/fonts/type1/adobe/utopia/putr8a.pfb

If you have a metric file (for OpenType fonts, metric files have extension‘.afm’) then if the metric file is in the same directory FontForge will detect it. You can be explicit using,

 File > Merge Feature Info

Now,

File > Generate Fonts

Adapt the dialogue to ‘truetype’, batter the filebrowser into placing the result somewhere (not always easy), then ‘Generate’. This will return errors and warnings. Initially, I’d ignore—FontForge always finds errors.

Note: I suggest you save as TrueType, not Woff. FontForge can not make Woff2 files.

(optional) Reduce the glyph set

I say optional, but… full font files can be massive—400k or more. Most sites do not need all those glyphs. If speed is your aim, glyph‐stripping is a priority.

Your problem is this—most posts that mention stripping glyphs toss the idea off in a sentence. It’s not that simple. Font editors are huge programs. They cost between £200 and £600. Professionals may have that on hand—I don’t.

Are there free versions? Yes, but unfortunately, media editing is one of those places where free software is no match for commercial focus. What you need, probably, is a program called FontForge. It’s one of those open‐software programs that is made by one man beating his way alone, seemingly forever. FontForge uses it’s own widget set. It’s horribly awkward to use, you’ll spend 20 minutes figuring out how to do a cut and save (clue!). But it can do the job, strip a TtueType file of thousands of glyphs.

You will run into problems. I stripped one font file to a ASCII‐range set, then found all my ‘i’ codepoints vanished. I’d ignored the FontForge warnings—essential connections and glyphs had been deleted. All I can say is—beware. On the plus side, you can make a massive savings this way—I cut down some files to a fifth their original size. That beats any compression algorithm.

Variable font files

Some fonts come in sets known as ‘variable’ files. These gather font‐variants together. The idea is you can tweak the font along an ‘axis’, rather like faux‐font provision by a browser. So you can get the base font with a ‘bold’ variant thrown in. Because they work on an axis, ‘variable’ font files can go a bit further than variant sets. A ‘variable’ font‐file constructed with a ‘weight’ axis can deliver fonts at any weight.

You must think carefully if your font is delivered as a variable font. The problem is that, as far as I know, it is impossible to construct or deconstruct a variable font using freeware. Let’s say you have a ‘variant’ font, and want to optimise for release. You pull the base font from the ‘variable’ package, and now have no ‘bold’ or ‘italic’ variant. Let’s say, because your source offers them as ‘static’ files, you can still find those variants. Good, but now you will be serving two files or more, after the variable font served only one. I said there are issues, big issues, and this is one of them.

(optional but the biz) Create woff2 files

There’s a host of online services. Generally these are parading size limitations and underhanded ‘logon and benefit’ schemes.

If you are on Linux, there’s the snappily‐named ‘snft2’ tool for OpenType fonts—on Debian under ‘woff‐tools’. And the ‘woff2_compress’ tool for TrueType fonts—on Debian under ‘woff2’. Woff2 can reduce files to 1/2 or 2/5 size. For production, I heavily recommend it.

Upload the file

I’m at the mercy of your server. Can you get the files into a folder then onto a URL? Good. Note that I suggest the files you serve are given a suffix. This is for what is called ‘cache‐busting’. See down a few headings.

Load font files into CSS

TrueType font files: this CSS,

@font-face {
  font-family: VollkornSC;
  src: url('/static/fonts/Vollkorn-VariableFont_wgh.ttf') format('truetype');
}

Woff2 compressed files: this CSS,

@font-face {
  font-family: VollkornSC;
  src: url('/static/fonts/Vollkorn-VariableFont_wgh.woff2') format('woff2');
}

Then you can use the font,

body {
	font-family: "Vollkorn", serif;
...
)

Other considerations

Preload

Alright. If you know the font is essential to the page, which it usually is, you can ask the browser to treat it as a priority. Bear in mind that declaration order in header files is important. You do not want these prioritised demands blocking the main CSS file, or JavaScripted content delivery.

TrueType font files: this HTML,

<link rel="preload" href='/fonts/Vollkorn-VariableFont_wght.ttf' crossorigin="anonymous" as="font" type="font/ttf">

Woff2 compressed files: this HTML,

<link rel="preload" href='fonts/Vollkorn-VariableFont_wght.woff2' crossorigin="anonymous" as="font" type="font/woff2">

Load strategy

There are various strategies for font‐loading. These are the options for the display property (technically, ‘descriptor’) in a ‘@font‐face’ rule, usable both in HTML tags and CSS,

‘auto’

Let the browser decide. Usually ‘block’

‘block’

Don’t draw text until the font arrives. The browser will prepare with placeholders

‘optional’

Only show if downloaded in time

‘swap’

(if necessary) Show text in fallback font until the font is downloaded, then swap the declared face in

‘fallback’

Compromise. Hide for 1/10 sec, swap if later possible, but only swap within, say, 3sec

‘optional’

Compromise. Hide then fallback, but this time, if the font doesn’t arrive, give up

None are perfect. ‘Swap’ can make for big layout changes, as the chosen font moves in. ‘Optional’ can leave the page in fallback fonts, which may kill a designer. Some sites are using JavaScript to boost their site yet avoid invisible displays or flashes of unwanted text. If you want to go deep, start reading the articles below.

That said, browser manufacturers know that designers love fonts, and are now optimising for that. This apparently important discussion is becoming less and less important.

Cache

Ah, can you set HTML response headers on your server? That would be useful. Unlike CSS stylesheets, fonts will rarely change, so you want a different strategy. The article below recommends,

public, max-age=31536000, immutable

You see that right. Keep the file anywhere that likes to stash information—in browsers, server chains, memcaches, wherever. Stash for a year. Assume the file will never change, and never need verifying. The value ‘immutable’ is not honoured by all browsers or server chains, but is a signal to many.

Now you see why I suggest suffixing font filenames. Fonts may be stashed for a year. To change them, you must force the code to look in a different place. A place like ‘Vollkorn‐2.woff2’.

Nginx config may look like,

	location /static/fonts {
            ...
            # Unnecessary search for woff2 compressed files
            gzip_static off;
            # 1 year
            add_header Cache-Control "public max-age=31536000 immutable";
        }

You get the drift. If you have done much work on the font files, then tuning cache headers is recommended.

Fallbacks

If you are using a fallback font, here is a trick. You can match the size of the fallback font to the size of the font being loaded. This means the font being loaded will not trigger a ‘layout‐shift’. This could even be fun? What if a Sans font grew a serif in a ‘swap’ move? What if a cursive font bent further into a handwriting font? At the time of writing this is only a proposal, but I’m watching this one. Read more at Simon Hearne on FMods.

Refs

Google, one thousand plus high‐quality fonts with open licences, and the Google API for web delivery, or download,

https://fonts.google.com/

Abobe notes on web usage of their general fonts (some similarity to Google provision), https://helpx.adobe.com/fonts/using/add-fonts-website.html

Open Font Licence notes, a licence used by some freeware. Gives an idea of what needs to be considered,

https://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=OFL

Ever reliable—CSS Tricks. The writer muddles this issue, but still a valuable way in,

https://css-tricks.com/snippets/css/using-font-face

This writer, who works for the Washington Post, does an outstanding job of exposing the issues, while making his way through them,

https://simonhearne.com/2021/layout-shifts-webfonts/

FontForge website,

http://pfaedit.org/

CSS display descriptor, CSS Tricks,

https://css-tricks.com/almanac/properties/f/font-display/