Skip to main content

Using Icon Fonts

This article was updated on August 19, 2013 to reflect the current way I implement icon fonts on my projects, which now includes the use of a feature test.

Icon fonts are awesome, and if you’re not already using them on your projects, you should be.

Icon fonts are incredibly light weight. The one for this site is just 5kb in size. Because it’s a single font file instead of multiple images, it requires just one HTTP request, which is great for site performance. They can be scaled smoothly to any size, and styled easily using CSS.

Here’s how I implement icon fonts on my projects…

Creating the font

There are a lot of icon fonts available, but I use IcoMoon. The free version contains more than 300 icons, with paid versions offering over 900.

More importantly, though, IcoMoon also offers a free app that lets you build your own custom font. This means you’re only using the icons you need, which keeps the file size down.

Full Disclosure: Because I talk about this app so much on Twitter, the guy behind IcoMoon offered me a free upgrade to their Ultimate Pack. I love the app so much that I paid for it anyways, and I had purchased the Essential Pack months ago.

To get started, head over to the IcoMoon app and select the icons you want. When you’re done, click the “Font” button at the bottom of the screen to open the font generator.

Before you download your font, you’ll want to reset the encoding to Private Use Area. This is section of unicode that has not been assigned any characters. Using the private use area for your icons helps ensure that screen readers don’t read them aloud.

The alternative would be to use standard characters (a to z, numbers, etc.). This can cause screen readers to say things like, “z Twitter,” which isn’t good for accessibility.

Once you’ve reset the encoding, click “Download.”

Adding the Icons to Your Site

When you unzip the download file, you’ll find a few items. The ones we really care about:

  1. The font folder.
  2. The style.css file.

Upload the files to your site

Open up your favorite FTP client, and copy the “fonts” folder into the same directory as your CSS file. If you need to put it somewhere else, that’s ok. You’ll just have to change a few lines of code in your CSS file.

Now, open up your stylesheet and add a new section for icons.

Embedding the font

Open up “style.css.” At the top, you’ll see this code:

@font-face {
font-family: 'icomoon';
    src:url('fonts/icomoon.eot');
    src:url('fonts/icomoon.eot?#iefix') format('embedded-opentype'),
        url('fonts/icomoon.svg#icomoon') format('svg'),
        url('fonts/icomoon.woff') format('woff'),
        url('fonts/icomoon.ttf') format('truetype');
    font-weight: normal;
    font-style: normal;
}

This tells browsers where to find the files for the font-family IcoMoon, and what the default style and weight are.

You’ll notice there are four different file types listed. Unfortunately (but not surprisingly), not all browsers support the same file type, so it’s necessary to include a few. You’ll also notice that eot is listed twice. This is to fix an issue with older versions of IE (again, big surprise).

I prefer to see SVG listed last, as it’s typically a bit bigger than the other filetypes and often not as well hinted. It’s used for iOS, which cannot load any of the other types.

After moving SVG to the end, your code should like this:

@font-face {
    font-family: 'icomoon';
    src:url('fonts/icomoon.eot');
    src:url('fonts/icomoon.eot?#iefix') format('embedded-opentype'),
        url('fonts/icomoon.woff') format('woff'),
        url('fonts/icomoon.ttf') format('truetype'),
        url('fonts/icomoon.svg#icomoon') format('svg');
    font-weight: normal;
    font-style: normal;
}

Add it to your CSS file.

Note: If you copied the “font” folder to a location other than where your CSS file is located, you’ll need to change the URLs in the @font-face declaration accordingly.

Update on 5/31/2013: In the comments, Nigel Anderson asked how many of these files are downloaded by the browser (and how that could impact performance). The answer: Browsers only download the first supported file in the list, even if they support more than one file type.

Creating a class

There are two ways to include an icon font in your HTML. One involves adding data-icon= and then the character for your icon to an HTML object.

The second method, which I prefer, is to assign a class to the icon font. Rather than remembering character values, you can add a Twitter icon, for example, by adding class="icon-twitter" to an HTML object.

IcoMoon gives you the option to use either method, but since the second is easier, let’s use that.

You’ll see the following code in the “style.css” file:

/* Use the following CSS code if you want to have a class per icon */
[class^="icon-"]:before,
[class*=" icon-"]:before {
    font-family: 'icomoon';
    font-style: normal;
    speak: none;
    font-weight: normal;
    -webkit-font-smoothing: antialiased;
}

This says that any class that begins with icon- should use the IcoMoon font family, has a style and weight of normal, and should not be read aloud by screen readers.

You’ll notice that it also includes the webkit prefixed font-smoothing property. This improves the clarity of the font. For good measure, I also include a non-prefixed version and text-rendering: optimizeLegibility;, which improves kerning on Firefox and newer version of Internet Explorer.

The final version of your code should look something like this:

/* Use the following CSS code if you want to have a class per icon */
[class^="icon-"]:before,
[class*=" icon-"]:before {
    font-family: 'icomoon';
    font-style: normal;
    speak: none;
    font-weight: normal;
    -webkit-font-smoothing: antialiased;
            font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
}

Copy that into your CSS file below your @font-face declaration.

Naming the icons

Next, we need to associate the individual icons with their unicode characters. IcoMoon does all of the heavy lifting here, creating human-readable classes for the icons.

In this example, I created a simple font with three icons: Twitter, Facebook, and Dribbble.

The “style.css” file contained this code:

.icon-twitter:before {
    content: "\e000";
}
.icon-facebook:before {
    content: "\e001";
}
.icon-dribbble:before {
    content: "\e002";
}

You’ll notice that we’re using the CSS3 :before selector. This inserts the specified content before whatever HTML object the class is applied to. The content property is used to define the unicode character.

You can copy this code directly from “style.css” (without any modifications) into your CSS file.

Using icons in your HTML

Now that you’ve done all that, including icons in your HTML is insanely easy.

Using my example font above, if I wanted to include a Twitter icon on my site, I would just add <i class="icon-twitter"></i> to my HTML.

I use the <i></i> tags because they’re small, no longer used for italics, and there’s something logical about “i is for icon.” Also, it’s what they do in Twitter Bootstrap.

Update on 5/24/2013: In the comments, Michael Barrish correctly points out that <i> is still a perfectly valid HTML element. What I meant to say was that the newer <em> element is the preferred way to italicize, because it carries not just stylistic but semantic meaning. Accordingly, I use <i> for my icons.

Don’t forget to leave a space between the tag and the supporting text. For example, use:

<i class="icon-twitter"></i> Twitter

Not:

<i class="icon-twitter"></i>Twitter

Styling icons

Because the icons are a font, they will inherit the styling of their parent container by default. However, you can apply additional styling using CSS.

For example, if you wanted all icons to have a shadow, you could add the text-shadow property to [class^="icon-"]:before, [class*=" icon-"]:before. You can also add gradients, hover effects, CSS3 transitions and more. One limitation: the icons can only be a single color.

I like my social media icons to have branded colors, but still display the default hover behaviors. Here’s the code I would use to achieve that with the Twitter icon:

a .icon-twitter {
    color: #41b7d8;
}

This code says that when a Twitter icon is used in a link, it’s color should be #41b7d8, which is Twitter blue.

In my base CSS, links on hover turn black darken and are underlined. With the code above, the icon would still be underlined, but would be Twitter blue. We can fix this by adding a hover color:

a .icon-twitter {
    color: #41b7d8;
}
a:hover .icon-twitter{
    color: #005580;
}

Branded colors

While by no means comprehensive, here’s a list of popular social site colors to get you started.

Accessibility considerations

Icon fonts are typically not read by screen readers. For accessibility reasons, you should not rely on the icon alone to convey meaning.

There’s a simple CSS class you can use to include supporting text in your HTML but position it off screen. If you wanted to display a Twitter icon, for example, you would use this code:

HTML

<i class="icon-twitter"></i> <span class="screen-reader">Twitter</span>

CSS

.screen-reader {
    position: absolute; 
    top: -9999px; 
    left:-9999px; 
}

Because the text wrapped in the .screen-reader class is still displayed, screen readers will detect it in the HTML and read it out loud. But because it’s positioned off screen, sighted users will not see it.

Browser support

Icon fonts work in Firefox, Chrome, Opera, Safari and the latest versions of Internet Explorer back. They work in iOS and Android, but not Opera Mini. Strangely, they don’t work in IE9 on Windows Phone 7. This has been fixed in Windows Phone 8.

While @font-face embedding has been supported since IE 5, the approach detailed in this article uses pseudo selectors to include icons in the HTML, and that’s only supported back to IE 8. IcoMoon includes a JavaScript file named lte-ie7.js that’s supposed to provide support for older browsers, but I’ve never gotten it to work, and several others have mentioned running into issues with it in the comments section.

I treat icons as a progressive enhancement, and use a simple feature test to check for support.

Feature test

Browsers that don’t support @font-face will sometimes display empty boxes where the icons should go. This looks ugly and can sometimes overlap with text, making it difficult to read. I use a simple JavaScript feature test to check for @font-face and pseudo selector support.

Download the script from GitHub and include it in your <head> element:

<script src="font-face-feature-test.js"></script>

This adds a .font-face class to the <html> element when both @font-face and the :before pseudo selector are supported. In my CSS file, I prefix the icon names with that class, so that they’re only activated when a browser has the proper support:

.font-face .icon-twitter:before {
    content: "\e000";
}
.font-face .icon-facebook:before {
    content: "\e001";
}
.font-face .icon-dribbble:before {
    content: "\e002";
}

You can also use this class to change what content is displayed based on whether or not the browser supports icon fonts. For example, you might show an icon for supporting browsers, and plain text for older browsers. Here’s an example:

HTML:

<span class="if-font-face"><i class="icon-twitter"></i> <span class="screen-reader">Tweet This</span></span>
<span class="no-font-face">Tweet This</span>

CSS:

.if-font-face,
.font-face no-font-face {
    display: none;
    visiblity: hidden;
}

.font-face .if-font-face {
    display: inline;
    visibility: visible;
}

Using icons today

Despite these considerations, icon fonts are very well supported, highly-flexible, and ready to be used on web projects today. Their small size and crisp resolution make them a versatile addition to responsive web development.

Referenced & Useful Resources

  1. IcoMoon
  2. Icon Fonts are Awesome by CSS-Tricks
  3. Trent Walton on why he switched to icon fonts
  4. Typekit on Windows Phone 8 Support

62 Comments

Leave a comment or contact me on Twitter at @ChrisFerdinandi.


Adam Axon

Thanks for this Chris, really helpful little article. I was playing around with the site a few months back and couldn’t figure out how to make it work so this is great!


Chris Ferdinandi

@Adam Axon Glad I could help, Adam!

It’s worth mentioning that the IcoMoon app has improved remarkably over the few months. It used to just provide a single font file that had to be converted using another tool at Font Squirrel. The full font file suite was added a few months back, followed by all the styling and javascript.

That’s another reason why I like to promote the tool so much. The developer invests a lot of time into creating new icons and making the product better.

Have fun!


Joel and Amber

Oh cool, I like that you have all the social media colors there, that’s super helpful, thanks!



Rafael

Muito bom o seu artigo – Very good your article. But the project reponsive priority is performance and a request for more html can harm the mobile user, because of this I have been asking for a suggestion, it’s worth using the icon-fonts now?


Rafael

Adding to the comment I said earlier, performance to take the content to the user correctly to not push him away before you even have a good experience.


Chris Ferdinandi

Hi Rafael – I agree, performance is a priority for mobile users (all users, really).

That’s the great thing about icon fonts. If you’re going to include icons on your site, an icon font is just a single HTTP request, the file is incredibly small, and the icons that result are crisp, scalable, and easily styled with CSS.

Responsive design is a reason to use icon fonts.


Rafael

Thanks for the reply Ferdinand, but before reading I had already decided to use it and no doubt your article helped a lot. With this will reduce the file size of my sprite that I will mount.


Kathryn

I have used icon fonts on my website, but as you mention with problems with screen readers reading ‘z Twitter’ I have the problem where Google results are appearing as ‘VAbout us’, where the designated letter value for the icon is being read as text … very frustrating!


Chris Ferdinandi

@Kathryn – This is where using the Private Use Area in unicode can help. PUA is a set of unused characters that you can assign to whatever you want. Using these will ensure that screen-readers (and Google) don’t display random, awkward letters.

From the tutorial…

Before you download your font, you’ll want to reset the encoding to Private Use Area.

IcoMoon just added something else called Ligature support, which lets you use whole words for icons (so Google and screen-readers would read it as “Twitter” instead of “z” in your example). However, browser support for this is very poor, so I don’t recommend you use it just yet.


Kathryn

@Chris – thanks for your response. The icon set that is being used on the site is not the one you have mentioned here . But I might consider changing to use the IcoMoon set as it seems to offer much more flexibility. Cheers. Kathryn


Chris Ferdinandi

@Kathryn – Ah yes! I ran into the same problem with some other font sets. If you like the current icons that you’re using, IcoMoon actually lets you import in existing icon fonts and effectively “build your own” – letting you set the characters that align to each icon and so on.

The added benefit of that approach: much smaller icon sets. Instead of a 25 to 50kb, you end up with nice, lightweight files (my admittedly small font set is about 4kb), which is really great for performance.

Best of luck!


Natalie Kane

Thank you so much for clearing this up for me! I’m very new to icon fonts, and found a lot of the documentation to be very unhelpful, but your explanation was brillant, so thanks!


Simone Silvestroni

Well done article Chris. I’m an heavy user of this techniques. I just use fontello.com for subsetting and creating my icons, as they have several well known ready icon sets. Cheers.


Chris Ferdinandi

@Simone – I’d not heard of Fontello before. Cool app! I’ll probably be sticking with IcoMoon, particularly since they have a Chrome plugin that works offline, but I think Fontello would make a great addition to a web developer’s toolkit as well.


Simone Silvestroni

@Chris – Yeah it’s a great tool, very handy especially since they give you a .json configuration file you can use to start from where you left if you’re on another browser/computer/office (and also you can use with your team so everyone can work on that, if needed).

But I’m going to try IcoMoon also :)


Thijs Van de Velde

Great post! I’ve been using fontcustom (http://fontcustom.com). It’s a command line tool that compiles or watches a folder with svg icons, and converts them into an icon font, while writing out all the nessecary CSS for you. Very handy as well!


Chris Ferdinandi

@Thijs – That’s another cool tool I didn’t know about. I think I’d still prefer to use something with more of a GUI, but the auto-compile feature on Font Custom is an awesome idea.

Does it allow you to specify what characters get assigned to each icon? One thing I love about IcoMoon is that you have the ability to use private use area unicode characters (and now ligatures as well) to avoid screen reader weirdness.



Chris Ferdinandi

@Simone – Glad you like it as much as I do. One of the few apps I use on every single project.


Thijs Van de Velde

Fontcustom uses private use area unicode. There’s no ligature support yet and you can’t choose the unicode positions for now, but I believe they’re working on that.


Chris Ferdinandi

@Thijs – Nice. I’ll be keeping an eye on that project as well, then. Cheers!


Michael Barrish

I’m another IcoMoon believer. You do an excellent job here of making it easy for folks to jump right in.

One small nit: It’s actually still correct to use the i element for typographically italicized text. I mean, correct according to HTML5. See http://dev.w3.org/html5/markup/i.html.


Chris Ferdinandi

@Michael Barrish – Could catch! <i> is still a perfectly valid HTML element. What I should have said (and indeed, I may update the article to reflect this) is that the newer <em> element is the preferred way to italicize, because it carries not just stylistic but semantic meaning. Accordingly, I use <i> for my icons.


Michael Barrish

@Chris Ferdinandi – At the risk of being perceived as the web developer equivalent a fussy grammatician, let me say that the em element is actually intended for stress emphasis — i.e., something you’d pronounce with greater umph — not typographically italicized text. Here’s a first-rate HTML5 Doctor article that explains not only i and em but b and strong: http://html5doctor.com/i-b-em-strong-element/. (You’ll note that the HTML5 spec redefined i and b so that each now carries semantic meaning.)

For what it’s worth, just about every developer gets these elements “wrong.” :-)

Anyway, I mention this stuff only because it effects the experience of screen reader users, who hear words emphasized when they should not be.


Chris Ferdinandi

@Michael Barrish – I believe you and I are are saying the same thing.

“The em element is actually intended for stress emphasis…” Agreed. That’s what makes it a semantic rather than a stylistic element. That said, the default browser behavior for stylistically showing that emphasis is italics. You can, of course, change that to whatever you’d like and it would still be a perfectly valid element, but almost everyone uses the default italics for the <em> element.

Based on my readings of <i> and <b> on the W3C website, those elements are still purely stylistic and non-semantic. Are you interpreting it differently?

http://dev.w3.org/html5/markup/i.html
http://dev.w3.org/html5/markup/b.html


Michael Barrish

@Chris Ferdinandi – I find this discussion quite interesting, which probably says something about me.

Anyway, yes, I do have a different interpretation of what the W3C is saying.

Here’s the rub, as it were, from http://dev.w3.org/html5/markup/i.html:

“Although previous versions of HTML defined the i element only in presentational terms, the element has now been given the specific semantic purpose of representing text ‘offset from its surrounding content without conveying any extra emphasis or importance, and for which the conventional typographic presentation is italic text’.” [emphasis mine]

So the i element now has semantic meaning — a meaning that is distinct from the meaning of em, which is simply: “a span of text with emphatic stress” (http://dev.w3.org/html5/markup/em.html).

Notably, the W3C redefined the b element in a similar vein to i, tying the revised definition to conventional typographic presentation, as distinct from emphasis or importance (which are exclusively reserved for em and strong, respectively):

“Although previous versions of HTML defined the b element only in presentational terms, the element has now been given the specific semantic purpose of representing text “offset from its surrounding content without conveying any extra emphasis or importance, and for which the conventional typographic presentation is bold text”. [emphasis mine](http://dev.w3.org/html5/markup/b.html)

A meta note: In this comment I used em a few times to indicate emphasis. I didn’t use i because it wouldn’t have been correct. However, had I mentioned Jeremy Keith’s book HTML5 For Web Designers (http://www.abookapart.com/products/html5-for-web-designers), I would have wrapped the title in an i element, since that’s the conventional typographic standard for book titles.


Michael Barrish

@Chris Ferdinandi – Unfortunately my attempts, in my previous message, to emphasize specific portions of quoted text with the em element didn’t work because blockquotes are already set as all italic. No biggie.


Chris Ferdinandi

@Michael Barrish – They may be describing it as semantic, but I don’t see how that’s actually different than its previous definition and usage, or in what way it actually adds anything but stylistic value.

Essentially they’re saying, “Nothing about this text is different except how it looks.” What’s semantic about that?

I too am enjoying this discussion immensely!


Michael Barrish

@Chris Ferdinandi – In looking at this again, I had the same reaction as you! How is the redefined i element any more semantic than its non-semantic predecessor?

I have no idea what the folks who hashed out the redefinition would say here, so I’m left to guess. And my best guess comes from what the HTML doctors wrote about this at http://html5doctor.com/element-index/:

[The i element] represents a span of text in an alternate voice or mood, or otherwise offset from the normal prose, such as a taxonomic designation, a technical term, an idiomatic phrase from another language, a thought, a ship name, or some other prose whose typical typographic presentation is italicized.

Only use i when nothing more suitable is available — e.g., em for text with stress emphasis, strong for text with semantic importance, cite for titles in a citation or bibliography, dfn for defining a word, and var for mathematical variables.

If italics were the typical typographic presentation of only one type of thing — say, book titles — no one would have a beef here: i would mean book title. But i is actually used for a long list of things, things that for the most part aren’t related, except in the sense that the English language has evolved in such as a way that they’re all typically presented in italics. The HTML5 redefinition groups together all these disparate things under the rubric of “a span of text in an alternate voice or mood, or otherwise offset from the normal prose.” I’m guessing that this is where the authors of the redefinition would say that they established semantic value for the lowly i element. But did they? Or did they merely stretch the definition of semantic past the breaking point? I think they did the latter, mainly.

However, this doesn’t, for me, mean that we should replace all instances of em with i. Far from it. Unlike i, em has a clear semantic meaning and should be used accordingly: to indicate emphatic stress. This is distinct from simply applying italics required by typographic convention, which is the domain of i. If we use em in place of i all the time, we end up making a semantic mess.

Now, so far as I know, no one has yet died as a result of a “semantic mess,” and so one might say that this is all just semantics about semantics. Still, I believe you would agree that a certain devotion to the details of our work is the essence of craft. In any case, it can be fun sometimes to talk about.


Nigel Anderson

Hi Chris

great write-up. I’ve just started using iconmoon and it’s a great tool. The documentation is excellent, but your piece is a nice accompaniment.

One thing I’m unsure of in terms of performance: that long list of font filetypes. How many get downloaded? Is it just a question of the first that works rather than all of them? [Surely the answer must be ‘yes’, but I’d like to hear someone say it…]


Chris Ferdinandi

@Nigel – Great question! Most browsers download the just first file on the list that they support and use that (another reason why I like to put the SVG file type, which is widely supported but much larger than the other three, last). If they support multiple file types, they’ll stop after the first type that’s supported.

More info here (I confirmed in Chrome using the Developer Tools).

I should update the tutorial to reflect this.


TJ

Do you know of any way to prevent IE7-IE8 from downloading the font-face files? Some CSS hack? I’ve had problems with font rendering in those IE versions, so I’ve hidden my font icon styling in a media query, which IE7-IE8 can’t interpret. That still doesn’t stop them from downloading the .eot files though.

I know I can use conditional comments, but I prefer to put the font-face styles in the main .css.

Thanks.


Chris Ferdinandi

@TJ – Have you tried using the JS snippet? IE supports the rendering of embedded fonts all the way back to version 5. Where it gets stuck is with :before and :after attributes.

The JS file that IcoMoon provides finds anywhere that you’ve included a font and adds some inline styling to help older IE browsers interpret the snippet and render the file.


Vera

Hello,
Thank you for this tutorial. It has made order of most things in my mind.
A newbie question: I am using the Protostar theme as basis for my own design, and it implements Iconmoon already. I liked the Iconmoon effect a lot, and wanted to use the font in other places, to which it wasn’t assigned.
How do I add icons which are not included in the font provided with the template?
Thank you,
Vera


Chris Ferdinandi

@Vera – Prostar appears to be a Drupal theme, and unfortunately, and I don’t have a lot of familiarity with that CMS. That said, at a high level, what you’d want to do is:

  1. Import the existing icon set SVG file into the IcoMoon app.
  2. Make any updates you’d like.
  3. Export the file as a new icon set (make sure you keep the naming conventions the same).
  4. Replace the existing icon set files in your theme with the new ones.
  5. Open up the stylesheet, locate the icon styles, and replace those with the new code as well.

Vera

Chris,
Thank you for replying.
It’s Protostar and its Joomla!, not Drupal. :)
In general it seems clear, only I am not sure I how to make sure I keep the naming conventions the same. Could you elaborate here, please, before I do some damage, lol?
Thank you,
Vera


Chris Ferdinandi

Yes, sorry. What I meant was, if the icon font is named protostar-icons.ttf, protostar-icons.woff, etc. use that as the file name when you download your finished font set in IcoMoon.

Also, if there are any icons that are used in the theme templates, make sure you keep the class names for those the same (for example, .icon-home) if you change the icon associated with it, or at least go in and update the class in your HTML.

Hope that helps!


Vera

Hi Chris,
Thanks for the clarification.
I have attempted to follow your instructions:
1. Imported the SVG file into the app.
2. Selected the icons I wanted to add.
3. Exported the new font .zip folder in the same name.
Then I discovered that the icons I have imported into the app were stripped of their names and values (content). They all became “untitled”.
I went back and found how to give them the name they had before with the Edit function – but not to value (content).
Now the question is:
Is that important? If so – how to fix that? Prefferably – in the font app, not in the individual places the icons are taken from…
Oh, and one more thing: there are more than one CSS file in the bootstraps and the template which have the icons. Do I need to change them all?
Thanks,
Vera


Chris Ferdinandi

@Vera – You can set each icons content value on the download page. The app provides the CSS for your specific font set. Without knowing what each of those files in your theme contain, I can’t really say what should happen there.


Vera

Thank you, Chris.
While waiting for the reply I got to playing with the files, and discovered that the value does not matter, really. However, what DOES matter and I couldn’t make it happen for some reason, whatever setting I used, is the multiple classes per icon. Like this:
.icon-print:before,
.icon-printer:before {
content: “\e013″;
}
I must be missing something.
Also, yes, the template CSS file does need changing, as well, if it contains the icons.
In the meanwhile, to make it happen, I have just added the missing multiple classes when required manually in both the CSS fies as well as the js file.
If you know how to make it download in the multiple way – please do tell, for the future. :)
Thank you,
Vera


TJ

@Chris — Thanks for the response. The icomoon JavaScript polyfill never worked for me. I was able to implement FontAwesome’s “expression” CSS trick. The problem was never getting it to technically “work” in IE 7-8. The problem was getting it to work consistently. In IE8 when I went live some of the font placeholders were just displaying as boxes, as is discussed here:
http://stackoverflow.com/questions/12130323/font-awesome-fonts-show-up-as-boxes-on-ie8

Somtimes all the icon fonts showed as boxes. Sometimes half. They’d reappear on hover. It’s a terrible experience for a user.

It appears to be some strange FOUT issue or some race issue where the font file hasn’t been downloaded quick enough and IE8 just starts rendering too early. A variety of “fixes” have been suggested, such as forcing the browser to re-download/refresh the .css file. They were all hacky and grotesque.

To make matters worse, this is one of those bugs that can’t be easily and consistently reproduced. If I had not seen it with my own eyes, I may have gone live with it never knowing that a good chunk of IE8 users were randomly seeing a shambles layout. I never found any solution that I could be confident in and I decided it’s simply not worth IE8. FontAwesome’s own github issues forums discuss this here:
https://github.com/FortAwesome/Font-Awesome/issues/295

I’ve gone through many of the github posts and it appears that even FontAwesome has thrown up its hands and given up trying to resolve this IE8 issue. It just sits there like a water stain on a 20 foot ceiling. Noone can do anything about it, so we’ll just ignore and hope IE8’s browser share goes away as soon as possible.

So, I’m left where I originally started:
1) Find a way to prevent IE7-8 from downloading the font files while serving it to everyone else, or 2) abandon font files altogether and just go back to image sprites with the maintenance hassles and memory decompression flaws that method has.

Thanks.


Chris Ferdinandi

@TJ – Wow, thanks for the thorough analysis. I’ve not really used the JS solution myself, but in testing, I seem to recall seeing similar behavior. I wonder if putting it above everything else in the header would make a difference?

As for a way to selectively serve the font file, you could try using Modernizr to feature test for @font-face support.

Then in your CSS you could include your styling like this:

.fontface [class^="icon-"]:before,
.fontface [class*=" icon-"]:before { ...}

.icon-twitter:before { ... }

It’s a little more specific than I usually like to get with my CSS, and the font-file will still download, but it won’t serve any icons unless the browser supports it.


Chris Ferdinandi

@Vera – If you’d prefer, you can manually rename any of the classes IcoMoon spits out. As long as you use the right content: "" value, you’re all set.


TJ

@Chris — Thanks. I was actually doing something similar. I loaded the font files for everyone, then just put the CSS declarations into a media query:
@media only screen, print {
/* font file rules go here, where IE7-8 can't see it */
}

But it kept nagging me that I was having IE7-8 download the font files unnecessarily as well as the fallback image sprites that I was showing them in place of the font file placeholders. It just felt wrong to do this double download, so I originally took down the font files altogether and went back to image sprites. I don’t like the sprites and am still holding out hope that a solution is out there. My website’s IE8 browser share is still too significant for me to provide a degraded experience.

By the way, I just did a google search for “ie9 font icons problems” and the results suggest this issue may actually effect IE9 as well. If that’s the case, I might as well throw in the towel altogether.


Chris Ferdinandi

@TJ – I’ve tested this quite a bit on IE 9 and haven’t had any issues. And I agree, the double-download feels wrong. I treat them as a progressive enhancement, so I don’t provide a replacement file for IE 8 and lower.


TJ

@Chris — I’m glad that IE9 isn’t a problem. I never experienced these issues on a dev. server where latency is so low. It’s only when I went live in the real world that it happened. I think I’ll monitor FontAwesome and icomoon’s github pages a little while longer before deciding to opt back into the double-download.

By the way, on an unrelated note, I noticed you use Quick Cache, but it doesn’t regenerate the page when new comments are posted. At least not until the cache is flushed via wp-cron. There’s a plugin called “Quick cache comment garbagecollector” that patches this, but I haven’t tried it.


Chris Ferdinandi

@TJ – By the way, it’s not @font-face that’s the issue, but the use of the :before selector. Any alternative approach that’s less convenient but better supported:

  1. Instead of [class^="icon-"]:before { ... }, use .icon { ... }.
  2. In your HTML, use something like <span class="icon">ICON-CHARACTER-HERE</span>

By setting anything with the .icon class to pick up the font, and then putting the character within the span tags, you avoid use of the :before selector that trips up older versions of IE.


Chris Ferdinandi

@TJ – Regarding QuickCache: According to their documentation, I believe by design it serves uncached versions to commentors so that at least folks like you can see updated comments. Not perfect, but a worthwhile trade-off.

I’ll definitely give that other plugin a look, though.


TJ

@Chris — Thanks. I was considering putting the characters directly in the HTML, as you’ve suggested, but I just felt that was a bridge too far. Now, if there were no IE7-8 square box issues, I would do it in order to avoid the icomoon polyfill or the bad performance of CSS expressions. I was thinking about trying “FOUT-B-Gone” to see if that fixed it, but it’ll probably conflict with the google web font loader which also fixes FOUT.

Icon fonts turned out to be one of those things I got excited about, researched, and implemented, and then I crashed into the brick wall of IE. Well, eventually IE7-8’s browser share will shrink to where IE6 is and we won’t have to compensate for it anymore.


Vera

Chris,
Yes, thanks, I figured this out while playing with it. What I was wondering is why the app has the option for multiple names, but does not ressult in multiple name CSS… It seemd strange, like a bug – or me missing some piece of information, which I always turn to first when talking about coding. :)
For the benefit of any other person who might be facing the same issue:
I also discovered another CSS file in the theme I am using which makes it RTL in the bootstrap area, and there it switches the navigation icons: Next, Previous, First Last. So after changing the fonts in the other files, these 4 icons just wouldn’t play correctly until I discovered it, and replaced them, too, with the same values.
Thank you so much for your help with this.
Vera


BL

Hi, I found this article very helpful! Do you, or anyone for that matter, have any suggestions for displaying the icon fonts when the IE 9/10 security setting for displaying downloaded fonts is disabled? I am working on a project where they need to be displayed, but due to security, this setting is disabled. I need to find a way around this. I am aware that I could simply change the setting to enable the downloaded fonts, but due to the circumstances I am unable to do that for all users of my audience. Has anyone encountered this issue and found any solutions? Thanks.


Chris Ferdinandi

@BL – Honestly, I’m not sure if there is a way to get around that. You’d essentially be ignoring a user’s desired selection, which is bad. Unfortunately, this is just a challenge of designing for the modern web. Control is an illusion.

If it were me, I would use text (or PNG sprite) fallbacks for the icons using the feature test trick above. This will also provide you with a working solution for folks on older Windows Phones, people using Opera Mini, IE 8 and lower (that don’t recognize the :before pseudo selector), etc.


BL

Chris,
Thank you for the quick response! And thank you for the advice, I will give the feature test a shot. When reading the post I thought that would end up being the best bet. Thanks!


Ryan B

Folks,
I am new to this so please bare with me. I am editing my style.css on my wordpress site and have a few questions for this.

My style.css already has a “font-face” section. My gut says I do not want to remove this and replace with the code suggested above. But rather add it. Is that accurate? Could you give me an example of what the code might look like if my current file says.

@font-face {
  font-family: 'FontAwesome';
  src: url("library/fonts/fontawesome-webfont.eot?v=3.0.1");
  src: url("library/fonts/fontawesome-webfont.eot?#iefix&v=3.0.1") format("embedded-opentype"), url("library/fonts/fontawesome-webfont.woff?v=3.0.1") format("woff"), url("library/fonts/fontawesome-webfont.ttf?v=3.0.1") format("truetype");
  font-weight: normal;
  font-style: normal;
}

Thanks!


Chris Ferdinandi

@Ryan B – That code actually looks pretty good. The only thing that’s missing is an SVG version (for iOS support). FontAwesome is actually one of the free fonts available for use with the IcoMoon app, so you might want to build a custom version of it there. But if you don’t, you should still be pretty good (minus the SVG issue, of course).


Ellen Biewald

Chris – Thanks so much for writing this, it is so wonderfully clear and helpful! Just what I was looking for!


Chris Ferdinandi

@Ellen – Glad you found it so useful. Best of luck!


Sudhakar C

I have downloaded the icons as fonts two times. But, icons which are listed any one of the files can be shown in browser. Icons which are listed in another file is look like simple rectangle box.

For example, please refer the following steps.

1. Download the home icon.
2.Download the pencil icon (changed the name i.e e6444)
3. Use those two files into the application. I can see home icon + rectangle box (or) pencil icon + rectangle box. Unable to see both home and pencil icon at a same time


Sudhakar C

facing this problem only in firefox


Sudhakar C

I am ready to share my simple sample. But, there is no option to share the samples


Chris Ferdinandi

@sudhakar – you should not be saving individual icon files, but generating an icon font that contains the same file in four extension types. Each of these files is identical, and contains all of the icons you’ve selected.

Different browsers supports different file types. I might recommend rereading the tutorial and starting over from the beginning.

Leave a Comment

Share links, code and more with Markdown.