Font-Embedding Icons the Right Way—A Legitimate Alternative to Images

Using fonts to display icons have shown potential but carry significant downsides. A slight adjustment to the method makes it ready for primetime.

When I released Iconic in font format it got a lot of positive feedback. However, it had one significant technical issues that kept it from being practical. The glyphs in the font had no logical assignment to Unicode characters, making the output semantically unsound. A few months back, Philip Shaw shared a much improved method for glyph assignment which I have implemented in the current version of Iconic. I thought it would be worthwhile to share that approach so that others may adopt it and that a standard can hopefully form.

It is common knowledge that Unicode has an amazing amount of characters, many of which are non-letter symbols (e.g., Arrows, Currency Symbols, Geometic Shapes, etc.). There are many Unicode symbols that represent common icons seen in interfaces. Therefore it makes sense semantically to bind icon glyphs with Unicode characters that represent the same basic subject matter. In doing so there are significant advantages around backwards compatibility. If the fonts do not load or the browser does not support font embedding it will fall back to the Unicode default (if one exists).

Example

The table below shows how the icon font for Iconic matches its own icons with Unicode equivalents. The third column shows glyphs from Iconic and the fourth shows the default Unicode glyphs. Note: If you’re reading this in an RSS reader, you will only see the default icons. Duh.

NameUnicode ValueIconic GlyphDefault Glyph
Sun0×2600
Mail0×2709
Key0×2602
Star0×2605
Moon0x263e

The Nitty-Gritty

I went through the specifics of code in my previous article, but I thought it would be worth showing again. Here is the basic CSS used (I have no doubt there are better ways to write this code, please feel free to share any feedback by commenting):

@font-face {
  font-family: 'IconicStroke';
  font-weight: normal;
  font-style: normal;
  src: url('iconic_stroke.eot?') format('embedded-opentype');
}
@font-face {
  font-family:'IconicStroke';
  font-weight: normal;
  font-style: normal;
  src: url('iconic_stroke.ttf') format('truetype');
}
.iconic {
  display:inline-block;
  font-family:'IconicStroke';
}
.bolt:before {
  content:'\26a1';
  font-size:32px;
  vertical-align:.15em;
  margin-right:.25em;
  color:#5d504f;
  opacity:.8;
  text-shadow:0px 1px 1px rgba(0,0,0,.3);
}

For this demo, I simply rap the content in a span, although you could also use an empty span tag to contain the icon for more control.

<span class="iconic bolt">Lightning</span>

The code above results in the example below:

Icon With Text

There are a lot of attributes applied to the example’s icon which show the advantage of using font icons. The icon can easily be resized, colored, rotated, scaled and adjusted with filters—all at runtime. No more re-saving images when you need to make a change.

Managing Extensibility

The most obvious outstanding issue is how to deal with icons that do not have a Unicode equivalent. Philip had a solution for that as well. Unicode has various private ranges which are sequestered for this exact purpose. Iconic uses the E000-EFFF range in these cases. Since there are no official assignments in this range, using them creates no semantic conflicts. However, any glyph that does not have a character assigned to it will display a placeholder (). This causes an issue for browsers that don’t support @font-face, so designers & developers still need to perform a check that a browser supports @font-face before employing this method.

Open Issues and Next Steps

There are still some issues that will need to be worked out, most notably a bug in Webkit that will not display glyphs at high Unicode hex values with the content:before rule. I have posted a bug and hopefully it will be fixed soon.

This is a major step in the right direction. From my perspective, this new method makes icon font rendering a legitimate and powerful approach towards displaying icons. I want to thank Philip Shaw who shared this idea and Yann Hourdel who helped me create the font creation scripts for Iconic. While Iconic is free and open source, I would like to offer these icons on services such as TypeKit and Google Web Fonts. The more demand there is for icon fonts, the greater chance they will be accepted at some point.

On a side note, the help I received through this process was one major reason why I open sourced Iconic. The new Iconic font faces were a community effort and it would not have happened without the tremendous help and feedback given by so many people. Speaking of feedback, I would love to hear your feedback on this method and how we can continue to improve upon this idea.

The Discussion

6 Comments

  • Great idea! I’ve seen fonts used as icons but always had that nag that it wasn’t semantic. The screen readers or those without @font-face support would see random meaningless characters scattered rather than any meaningful content. This is smart to map the characters to the already used names where applicable! Hopefully this catches on because it is indeed an elegant solution and is much better (ease of use, faster, scalable (for responsive designs), and less files/filesize) than using images as icons – even considering sprites! Thanks for the update and the writeup.

  • I spent some time hacking around with webfont icons and found there are plenty of unicode ‘characters’ that appear to be unassigned (not just various whitespace characters, but completely empty) For example ⁢ ->  , as well as whole tables of character listed as unssigned.

    These characters have the benefit that if the webfont is not supported the browser will not show anything at all, and maybe more importantly not take up any space either. This obviously has advantages for icons that are not matched well with existing Unicode characters, or where the icon is deemed purely presentational and therefore unworthy of a fallback character.

    HOWEVER, I have been unable to find out if there is a reason for these unasigned characters, and whether or not this would have potential issues further down the line. Regardless, it makes me uneasy – but it is potentially useful.

    On a side night, when using Iconic SVG to create and SVG font and the processing that to OTF and TTF – the OTF keeps the circular shapes correctly, however TTF turns circle shapes into ’rounded rectangles’, or something more like circles made from four curved lines rather than being a ‘proper’ circle.

  • D’oh, those empty unicode characters didn’t show up – the example range is: #x2062 -> #x206F

  • re: “Note: If you’re reading this in an RSS reader, you will only see the default icons. Duh.”

    Reeder.app on my Mac did fine.

  • The glyph for 0×2602 (labeled ‘key’) shows a gear and falls back to the default empty-glyph-square. Possibly not the correct code? Google Chrome 16.0.912.63 – WinXP SP3

  • This is great news… I was also thinking of building my own icon/symbol set, but really, I want to build an open library/framework for designers/developers to be able to keep a consistent set of icons without having to change their markup.

    Some Random Dude, I like you.

Leave Your Own Comment