Host your own web fonts

Mike Solomon

Web fonts are very popular these days, and sites like Google Fonts and Typekit make it very easy to use them on your website.

Hosting them yourself is also pretty easy. I recently moved away from Google Fonts for this site using this same process.

Selecting a font

First, you must select a font. Be sure that the license you have allows you to host it on the web. We will use Lato, which is also available on Google Fonts.

Making the font available for use

Let’s say we want to use Lato and allow for bold, italic, and italic bold. This is how we would make the font accessible from CSS using Google Fonts:

<link
  href='//fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic'
  rel='stylesheet'
  type='text/css'>

To self-host, the process is slightly different. First, we must download the files and put them in a folder, such as fonts.

Ideally we want to have each font variant (regular, bold, italic, bold + italic) in three formats: .woff for modern browsers, .eot for old Internet Explorer, and .ttf for other browsers. Font Squirrel has an online tool to convert easily between them if you’re missing any.

Now it’s just a matter of some simple CSS:

/* Normal */
@font-face {
    font-family: 'Lato';
    src: url('fonts/Lato-Regular.eot');
    src: url('fonts/Lato-Regular.eot?#iefix') format('embedded-opentype'),
         url('fonts/Lato-Regular.woff') format('woff'),
         url('fonts/Lato-Regular.ttf') format('truetype');
    font-style: normal;
    font-weight: normal;
    text-rendering: optimizeLegibility;
}

/* Italic */
@font-face {
    font-family: 'Lato';
    src: url('fonts/Lato-Italic.eot');
    src: url('fonts/Lato-Italic.eot?#iefix') format('embedded-opentype'),
         url('fonts/Lato-Italic.woff') format('woff'),
         url('fonts/Lato-Italic.ttf') format('truetype');
    font-style: italic;
    font-weight: normal;
    text-rendering: optimizeLegibility;
}

/* Bold */
@font-face {
    font-family: 'Lato';
    src: url('fonts/Lato-Bold.eot');
    src: url('fonts/Lato-Bold.eot?#iefix') format('embedded-opentype'),
         url('fonts/Lato-Bold.woff') format('woff'),
         url('fonts/Lato-Bold.ttf') format('truetype');
    font-style: normal;
    font-weight: bold;
    text-rendering: optimizeLegibility;
}

/* Bold + Italic */
@font-face {
    font-family: 'Lato';
    src: url('fonts/Lato-BoldItalic.eot');
    src: url('fonts/Lato-BoldItalic.eot?#iefix') format('embedded-opentype'),
         url('fonts/Lato-BoldItalic.woff') format('woff'),
         url('fonts/Lato-BoldItalic.ttf') format('truetype');
    font-style: italic;
    font-weight: bold;
    text-rendering: optimizeLegibility;
}

Your fonts should now be available. Be sure to adjust the url paths if you place your fonts in a different directory.

Applying your font

Simply apply your font in CSS as usual (this will also work with Google Fonts or Typekit):

body {
  font-family: Lato, 'Helvetica Neue', Helvetica, Arial, sans-serif;
}

Now you’re good to go!

Extreme optimization

If you really want to get fancy, Google Fonts has a feature called subsetting that lets you strip unused characters out from the font before transmitting it to clients, saving bandwidth.

You basically have two options if you want to do it yourself. The easy way is to use FontSquirrel’s excellent Webfont Generator, and use the subsetting options there.

The hard way is complicated and you will need to work out the exact details, but a basic setup would be:

  1. Determine what characters you use

    If you have a static website, you might be able to do this fairly easily, perhaps by finding every character displayed on any page (accounting for HTML encoding).

  2. Set up a pipeline to subset your fonts

    fontTools’ subset.py is probably the best way to do this, or the related version in Google Font Directory.

  3. Use the generated files as above

Before going down this route, you probably want to measure your maximum possible speed improvement and see if it’s actually worth the trouble.