Why And How To Use Icon Fonts

As great as images are, they present challenges in designing websites. They add file weight. They require additional http requests. They don’t scale well. Sometimes the best solution for using images in a responsive design is not to use an image.

Last week I offered an overview of a key problems with images in responsive design, specifically how to serve the most appropriate image to different devices. Today I want to consider icon fonts and how we can use them to replace some images on our sites.

Sosa icon fonts

The Advantages of Icon Fonts

Bitmap images don’t scale well. They can lose quality when scaled up and waste file size when scaled down. They require http requests for each image, further slowing load times. They’re also difficult to manipulate without reworking the image in an image editor.

Fonts don’t have these problems. They scale well and don’t require http requests for each character. While we think of fonts in terms of the characters we use for writing, they’re really just shapes. What if instead of those shapes being letters, they were icons?

Icon fonts are awesome. So says Chris Coyier. The example page he created about icon fonts offers 6 reasons why they’re so awesome and I’ve added a few more. Icon fonts:

  • Scale easily
  • Change color easily
  • Include shadows easily
  • Can have transparent knockouts
  • Have good browser support in general
  • Can use text based css (still needs better support)
  • Can be designed on the fly (by making changes on :hover, etc.)
  • Can do anything image icons can do (change opacity, rotate, etc.)
  • Have smaller file sizes since they contain fewer characters than full typeface

Let’s see your bitmapped images do all that.

Icon fonts from Tipogram

How to Use Icon Fonts

The first step in using icon fonts is to find and embed the font. I’ll point you to a few places to find them later in the post. Once you have a font. you can use your favorite @font-face method to embed it. I recommend Paul Irish’s bulletproof @font-face syntax.

From here you typically have 3 options.

  • Wrap your icon in html
  • Use css generated content
  • Use the data-icon attribute

Wrap Icon Fonts in HTML

The first option is simple. Below I’ve used a span to wrap a character (in this case the letter ‘s’) and added a class to the span. The character has been mapped to a specific icon in the chosen font.

{code type=html}
s View Cart

To display the icon you use css to style .icon so it uses your chosen icon font.

{code type=css}
.icon {
font-family: ‘your-chosen-icon-font’;

Pretty simple, but it adds a meaningless character to your markup. The character also gets read aloud by screen readers, so while you expect it to be seen only as an image, a certain number of visitors will hear the letter ‘s’ read aloud.

Modern Pictograms icon font at Font Squirrel

Use CSS Generated Content

Let’s try to improve things a little. Instead of including the character directly in our html, let’s use some css generated content. Below I’ve removed the span and character and moved the icon class to the link. I’ve also added another class ‘cart’ to the link.

{code type=html}
View Cart

The magic happens in the css. First we assign the icon font to the icon class. Next we use the :before pseudo element on the cart class to serve the character. :after works as well when you want the icon on the right.

{code type=css}
.icon {
font-family: ‘your-chosen-icon-font’;

.cart:before {
content: “s”;

Once again the icon mapped to the letter ‘s’ would be shown. We’ve moved some html markup to our css, which is good, but screen readers will still read the character, which isn’t so good.

Use a Data-Icon Attribute

A similar method to the one above makes use of html5’s data- attribute. Here we’ll create a data-icon attribute.

{code type=html}
View Cart

As before we’ll add the chosen font to the icon class, but now we’ll create the character by referencing what’s in the data-icon.

{code type=css}
.icon {
font-family: ‘your-chosen-icon-font’;

.icon:before {
content: attr(data-icon);

The general ideas is still the same as above and it also comes with the same problem, that of the character being read aloud.

A Better Data-Icon Method

Trying to improve on the data-icon method above, Chris Coyier offers two methods, one when using an icon to enhance a word, and one when using a stand-alone icon.

Here’s his method to enhance a word (or phrase). We’ve added back a span with the same data-icon attribute as above. The span also includes the aria-hidden attribute with a value of true.

{code type=html}

View Cart


aria-hidden=”true” will prevent some, though not all, screen readers from reading the character aloud. VoiceOver in Mac OS X will say “html content” unfortunately. Still it’s better than having the character read by all screen readers and you can see it works in the video above.

The accompanying css should be mostly familiar by now. Note the selector is anything with the data-icon attribute.

{code type=css}
[data-icon]:before {
font-family: your-chosen-font;
content: attr(data-icon);
speak: none;

The last bit speak: none, shouldn’t be trusted, but why not include it just in case or for a time when it can be trusted. I’ll let you check Chris’ other method either at his post describing both methods or at the example page for icon fonts mentioned above.

Elevetaor signaling it's going down

What’s the Downside?

This is all sounding pretty good so far. Is there a catch? Is there a downside to using icon fonts? We’ve already talked a bit about one potential downside, that of screen readers, reading aloud a character you’d prefer them not to. How about some others.

  • They need to be rendered monochrome or with css3 gradients
  • You’re restricted to what’s available (unless you want to create your own)
  • Creating them can be time consuming

The first isn’t a major issue as long as you use icon-fonts appropriately. You won’t use them for everything, but for icons the color limitations aren’t much to put up with.

The last 2 items aren’t a huge issue either. Odds are what’s available will continue to grow and you’ll probably choose something available over creating icons yourself.

In the code above we’ve already seen the two main routes to solving the screen reader issue, aria-hidden in html and speak in css. One other possibility is better mapping of the icon to unicode characters. There are many, many thousands of unsigned code points in unicode that could be used for icon fonts that won’t be read aloud.

Foundation icon fonts fromZurb

Where Can You Get Icon Font?

Above I mentioned I would point you to some sources for icon-fonts. I’m sure there are more than what’s listed below and expect more people to be creating icon fonts in the near future as well.

And if you’re up for it you can always create your own icon fonts. Again I’m sure there are more tools for creating icon fonts than what I’ve listed below.


Icon fonts won’t be appropriate for all scenarios, but where they are they really are awesome. They offer so many benefits over using an icon image, most notably that they scale and maintain proportion and are easily manipulated in a number of ways.

They do have some small downsides, that aren’t much of a problem and one in screen readers reading characters aloud that the industry seems to be solving little by little.

Icon fonts certainly won’t solve all your responsive image problems, but the ones they do solve, they solve well.

Next week I want to look at another image solution that isn’t widely used. We’ll look at scalable vector graphics (SVG) as a potential replacement for some bitmapped images.

« »

Download a free sample from my book, Design Fundamentals.


    • I don’t really think it’s the same thing. Icon fonts have a more specific purpose than WIngdings and are being designed for that specific purpose.

      However why were Wingdings so awful? Maybe they were just ahead of their time.

  1. Nice article, thx for that. One thing I`m asking myself is: How can I get to have meaningfull names in my data-icon attribute. In the example you use the character ‘s’. The icon-font I want to use has someting like ‘e3e8’ as character data, but I would rather have something like ‘magnifier’ or ‘star’. Any ideas for that?

    Cheers, nic

    • Good question. I’m not sure if I have a good answer for you. I just did a little searching, but didn’t find anything. When I have more time I’ll try to search more.

      I’m thinking you need to use the CSS Generated Content method though that reads the character aloud to screen readers.

      I’m not sure if this would work, but maybe you could use Javascript to read your meaningful data-icon value and then have it convert that to the one the icon design used. That sounds like more work that it might be worth though.

  2. Great article on a generally unknown feature in web design. I have a question for you: what to do when foreign or special characters (such as ] or รก) don’t get rendered as icons but as themselves?

    • Thanks Raul.

      When the special character renders as itself, it’s because the developer of the icon font didn’t create an icon for that character.

      The fonts won’t render every character as an icon by default. It depends on how many icons were created.

  3. Steven, I forgot to say that on my local machine all characters (specific font is Sosa) have shown up without a hitch, but for the last few days when I upload the same code to my hosting service some characters refuse to appear as icons.They’re not A-Z,0-9 or regular punctuation signs. Could it be a web server change that I haven’t been warned about?

    • That’s different. It sounds like the icons have been designed then.

      I suppose it could be the server. It’s obviously aware the characters exist, since it displays them. Are you able to get any of the icons to display? Is it just the special character ones having problems?

      If none of the icons are appearing, I’d think the issue has to do with the fonts not being accessed on the server. Is your site on a platform like WordPress? It might be the characters are getting converted to an html entity or some other code and then converted through a CMS and somewhere along the way it’s skipping the icon. If that’s the case you probably have to find a way to stop the CMS from trying to make changes t the character.

  4. After hitting my head on the wall a hundred times, I finally found out why my Sosa font foreign characters didn’t show up as icons: I had typed this: . That extra quote messed the whole thing up. So let’s all kick back and relax: Sosa font is still great. Steven, thanks again.

  5. Hi, Steven, awesome tutorial, thank you!
    Can you help me?
    I used this line of the code “-o-transform: scale(1);” to scale my icons in Opera properly, however it didn’t help me. Maybe it is because of specifically these icons, that I am using – (removed link)
    Is it possible that something is wrong with them? What do you think? And thanks for your tutorial!

Leave a Reply

Your email address will not be published. Required fields are marked *