Using Fonts for Resolution Independent Assets

Whilst working on the upcoming redesign of the Clearleft website, I’ve been ensuring the website is resolution independent. In my last blog post I showed how to use SVG files on the web, and we are using this technique for the Clearleft Logo. There are a bunch of other assets, and for these we are using a custom web font.

Any single colour vector asset will work with this technique. Multiple colour vector assets will need to be a SVG file. But whilst SVGs don’t work in IE<9 and Android<3, web fonts work in almost every browser.

Retina vs Resolution Independence

Generating @x2 graphics feels a bit wrong to me. Sure, it’ll look great on a brand new Retina MacBook Pro or any recent iPhone, but what about the unknowns? We don’t know what resolution devices of the future will use. It isn’t safe to assume that all future devices will have either a 1x or 2x resolution. Let’s be Future Friendly and embrace unpredictability.

So without further ado, here’s the steps I’ve taken to use a custom web fonts for assets on the new Clearleft site.

Step 1: Exporting from Fireworks

We need to generate an SVG file for each asset we want to assign to a glyph in the font file we’re about to create. I’ve already detailed this process in Using SVG graphics today. If you’re using Photoshop, then you just need to save as an SVG.

Step 2: Installing FontForge

FontForge is a free font editor that works cross platform. It requires X11 to run and can be installed from within a package manager.

It can be a little tricky to install, but this guide will get you up and running on Mac OS X. It’s worth noting that as of Mac OS X Mountain Lion, X11 is no longer provided by Apple. You’ll need to install XQuartz instead.

Step 3: Creating the font

FontForge’s interface can be a little intimidating at first, but bear with me, we’re nearly there!

First, let’s create a new font. FontForge thinks it’s being helpful by generating a whole lot of empty glyphs. We don’t want those, so click Encoding, Remove Unused Slots.

Now let’s name our font. Click Element, Font Info and change the Fontname to whatever you like. We called our font Cleardings.

Font Info Window

Step 4: Adding the glyphs

You’ll need to add as many encoding slots as you have assets, by clicking Encoding, Add Encoding Slots. You’ll see a bunch of slots appear underneath. Click on the first one and click File, Import. Navigate to where you saved your SVG files and choose SVG from the format drop down. Now select the first asset. Boom! There’s your asset, inside a font!

Twitter Glyph

You need to map this glyph to a unicode value. Click Element, Glyph Info. If the asset represents an actual character, such as an arrow then assign it to the appropriate unicode character. Otherwise, set unicode value to something in the range U+E000 - U+F8F (eg U+E000), as these are for private use and are ideally suited to custom assets.

Glyph Info Window

You might find the asset is all the way over to the left, so click Metrics, Centre in Width.

Rinse and repeat for each asset. You’ll need to assign each asset to a different unicode value such as U+E002, U+E003 and so on. Unicode values are in hexadecimal format, and so are numbered from 0-9 then a-f. You might find it useful to change the following view option View, Label Glyph By, Unicode.


Step 5: Generating the web font

From FontForge, click File, Generate Fonts and save the file somewhere. We won’t be using this font directly, but using it to generate web fonts.

Now, go to the Fontsquirrel @font-face generator. Add your newly created font. Choose Expert mode and change the following settings:

  • Uncheck **Spaces** and **Hyphens** under fix missing glyphs
  • Choose **No Subsetting** to ensure your assets are all included.
  • I’ll leave it up to you whether you think this font should be web only or not.
  • If your font is small (<≈10kb), you might want to Base64 encode it, so that it’s embedded directly in your CSS

Click the download button and wait for your font to be generated.

Step 6: Using your Assets Font

I’ll leave it to you to place the generated fonts in an appropriate location and link to them from your CSS.

To use an asset inline, create a class for assets such as .asset and set the font-family to your custom web font. Now find the decimal value of your glyph by converting from hexadecimal to decimal using a tool such as Hex to Decimal Converter. If the decimal number is 57345, for example, use &amp;#57344; in your HTML.

To use an asset using pure CSS, apply it to a pseudo element such as .asset::before { … }. Set the content property to a slash (\), followed by the hexadecimal value. For example:

.asset::before {
    content: "\e000.";

One thing that worries me about using a glyph font is that characters mapped to the private use table will fallback to a placeholder glyph (&#57344). If you base64 encode your font and use CSS to set the content on a ::before pseudo element then you should never see a fallback font

This covers the basics of creating your own font for use on the web. You’ll now have a assets that look good at any zoom level, on any screen density. They should be slightly smaller in file size than an icon sprite, depending on the complexity of the vector and will work in almost all browsers.

Paul Lloyd created these single colour social icons. I especially like how he handled Flickr’s logo. Here’s a sneak peek at the new Clearleft site.

Clearleft website

And just to prove you’re not looking at images, here’s the same site with the font-size bumped up.

Clearleft website with font size increased

Addendum: If all this talk of messing about in the Command Line and dealing with X11 applications is giving you a cold sweat, I’ve been informed that IcoMoon is a great resource. It looks like it will do everything you need to create your own asset font.

Notice: Array to string conversion in /var/www/ on line 22

Fatal error: Uncaught Error: Function name must be a string in /var/www/ Stack trace: #0 /var/www/ tags(Object(page)) #1 /var/www/ require('/var/www/joshem...') #2 /var/www/ tpl::loadFile('/var/www/joshem...', Array, true) #3 /var/www/ tpl::load('post', Array, true) #4 /var/www/ site->load() #5 /var/www/ require_once('/var/www/joshem...') #6 {main} thrown in /var/www/ on line 22