Skip to content

24 ways to impress your friends

Displaying Icons with Fonts and Data- Attributes


Comments are ordered by helpfulness, as indicated by you. Help us pick out the gems and discourage asshattery by voting on notable comments.

Got something to add? You can leave a comment below.

Stefan Rechsteiner

Because of the usability-issue (braille-reader, screen-reader) you can use the abbr-tag to describe the use of your font-char, therefore most screen-readers will read-out the title-param of abbr and the user gets the meaning of the ‘icon-character’.

I’m not 100% sure, but as it seams NVDA, JAWS and VoiceOver for iOS this works — on Mac OS X (unfortunately) not…

Example: <abbr title=“Attachment Icon”>A</abbr>

Mark Hurrell

Probably also worth noting that although IE has supported font-embedding on the desktop since IE4, it’s not supported on the version of IE9 that comes with Windows Phone (up to 7.5 anyway)

Very cool trick. I’m only concerned about the a11y issues…

IIRC, it’s not all screenreaders. Apple’s voiceover is one of the few that read out loud generated content via css. But I’m not aware if the latest versions have added support for this in the rest of the gang: jaws, windows eyes and nvda.

Nicolas Gallagher

A couple of little issues in this recap of the font-icon technique.

1. :before and :after are pseudo-elements, not pseudo-classes

2. The @font-face technique that is referenced is not the most bulletproof method at the moment. This one is – Further hardening of the bulletproof syntax

3. The last testing results I read showed that most screenreaders (but not VoiceOver) don’t read CSS generated content (but probably should), and there are support issues for @font-face on mobile – Dingbat Webfonts: Great potential, but we see (and hear) accessibility issues

Federico Brigante

I think the solution to the accessibility issues would be really simple: use unreadable characters. There are characters which screen readers won’t read (such as ◯, ◉, ◎, and ⦿) so we could use them when making the icon fonts.


When using multitouch zoom in Lion the webkit-background-clip icons do get blurry. However, if you use ctrl/cmnd +/- to zoom in they look nice and sharp.

Odd, I hadn’t realized that they represented two different kinds of zoom before.


I have tried to make the process of making icon fonts a little easier. I’ve made a font generator, which presents you with a large number of icons (currently offering 310 icons). You can easily search and select the ones you want and then assign them to letters to generate your font.

You can check it out here:

A demo page with a few samples:

Using data attributes, as mentioned in this article, is smart. Doesn’t IE8 have any problem with content:attr() though? Up to now, I’ve been using class names, for each icon.


Probably the best solution for the screen reader problem is assigning the icons to the <a href=“”>supplementary private use area</a> blocks of unicode.

This is what Florent suggested in my <a href=“”>forrst post</a> regarding which characters are never read by screen readers.

I have not tried this and I’m not sure if there are any browser issues; but if it works, I will upgrade my <a href=“”>icon font generator</a> to use these supplementary characters.

Jeroen Hulscher

If the screenreader supports the aria-hidden selector it is a fairly good solution to the accessibility issue, but if a user uses his own stylesheet this will just show the character used.

I think this is a typical solution to improve the life of developers without keeping in mind the end-users. I do love this solution, but in the end the old-fashioned solutions might be more appropriate until this is fixed in both browsers and screenreaders.


@Emil How would you add that attribute to a CSS pseudo element?

This might also work:

.icon:before { speak: none;

By the way, I can’t figure out how to put links in my comments here on 24ways! Admins please fix my previous comment. And please enable some basic HTML tags? :/


This is a brilliant tip! Thanks Jon. It’s the kind of thing you could safely apply if making web apps targeted for an environment where you know exactly what browser they’re going to be run in.
Not sure I’d be happy using it in a production website where millions of people are going to be seeing it, many using IE — fortunately (?) I don’t get to work on those very much!

Gunnar Bittersmann

Thanks for sharing this tip.

Just don’t use random characters when there are appropriate Unicode characters like U+2665 ♥ available:
<a href=”/” class=“icon” data-icon=“k”>Favourites</a>
shold be
<a href=”/” class=“icon” data-icon=“♥”>Favourites</a>.

Using appropriate characters ensures that the desired symbols will be displayed (in some system font that contains a glyph for that particular symbol) even if the desired webfont is not loaded.

Check the Unicode charts for symbols.

Rachel Andrew

I love this idea, and used it recently (very simply) for the cheatsheet I put together for Perch –

I went back and forth as to whether to include the technique in the new version of CSS Anthology, ultimately deciding not to because of the accessibility concerns you mention. I don’t like to recommend something to a beginner audience that might have a bunch of caveats as to whether it should be used on a particular project. I’m not an accessibility expert though and I’d love to see this technique discussed by those who are.

Bevan Stephens

I love the idea of this but find the bad text aliasing in Firefox spoils it every time.

Until there is a way of doing: -webkit-font-smoothing: antialiased; in gecko, I will stick with sprites.


Jon, thanks for this excellent post – I’ve been playing with this approach for while and will definitely come back to your article.
Thank you :)

Mark Hurrell

To solve the semantic issues, try mapping your glyphs to the Unicode private use areas. That’s pretty much what they’re intended to be used for.

Also, you’ll want to use a robust font-embedding detection script before using in a live environment – loads of the webkit based mobile browsers report false-positives for @font-face support, so you’ll end up with loads of rogue (non icon) characters dotted around your page on those devices if you’re not careful.

Chris Garrett

Great article Jon. This technique has been brilliant for us as it’s drastically simplified the preparation and delivery of image assets on a lot of our mobile focused apps, where that really matters.

There has been suggestions to map the various glyphs to corresponding unicode characters (in Pictos case), which I think would greatly aid the accessibility issues. I would certainly adopt this approach in a bespoke typeface.

Chris Lilley

But why overload ASCII characters with unrelated meanings, just to make them appear as icons (even if you are trying to hide them, screen readers etc are starting to show generated text too).
This is what the Unicode private use area is for – use it.
Also, maybe time to re-examine your opinion that SVG support is ‘patchy’.
Claimer – involved in the development of PNG, CSS. SVG and WOFF.


Love this technique but I do wish all these articles had some kind of key for what browsers are supported. I know that may feel like a rather negative thing to dwell on whether the whole 24 ways concept is about a positive, festival calendar of ideas, but transparency is always a nice thing.

The unfortunate fact is that :before/:after pseudo elements aren’t supported by IE7 at all, which is still very much an important browser for many clients as we (the development community) have only just convinced our clients that IE6 isn’t an option!

Jon Tan

I agree with the thrust of your article, Jon, in so far as icons in web fonts have huge potential. However, assuming we eventually have great screen rendering and sufficiently refined control in CSS, they ought to be mapped to unicode code points that already exist for a vast majority of the common symbols we need in interfaces.

My view is that other techniques should be a last resort, and dingbats should be avoided for all the right reasons. For more on why, see my article on icons, unicode, and dingbats and some of the comments, in particular the succinct comment of Joe Clarke .

For projects that warrant it, a custom typeface could easily be created, using the correct unicode symbol mapping, and private use code points for custom icons. Wouldn’t that be something!

Thanks for the interesting read. :)

David Bushell

I love the idea and I’m all for ingenuity in development but why use this when a more apt technique exists? All modern browsers support SVG as background images (and in the image element).

Considering the accessibility concerns and difficulty in creating custom fonts, I’m struggling to see any benefits here? Perhaps rapid prototyping is one, but then icons aren’t important at that stage. The ability to apply text styles is a marginal advantage if any, one could edit SVG icons just as easily.

I have a little SVG demo here:

Fallbacks for older browsers (IE7/8) is a little tricky but with a bit of progressive enhancement theory can be solved.

Dingbat fonts are a cute and esoteric idea, but I struggle to see a real necessity for them.

Jon Hicks

Thanks for the feedback everyone! The main point seems to be regarding the semantics of the characters used for icons. There’s a few points with this:

- Yes some characters can be mapped to existing equivalents (such as the heart symbol for favourites mentioned above), but in the scheme of things, this is the minority. Many icons don’t have equivalents. – Yes, the private area of unicode would be better (and also prevent the letter being read out), but this will add another layer of complexity in specifying the correct characters. If we has something like for this it would help a lot – In my mind, icons are just another form of language, but the labels associated with them are the most important. For me, its the labels where the semantics matter most (but if we can use an equivalent unicode character, so much the better).

It’s interesting that the aspect I consider the biggest obstacle – that you can only add new icons if you’re able to create a font – hasn’t been picked up. To me that’s a far bigger problem than semantics of the character used, as you’re relying on what the creator of the font has offered to serve all your needs! :)

Jon Hicks

@David Bushell – Simply presenting another option, rather than presenting it as THE option. The advantages are (re-iterating parts of the article):

- Someone without drawing skills can implement them – They’re scalable – They’re resolution independent – IE support isn’t an issue (although quality of the rendering is)

Thanks for the SVG sprites demo though – hadn’t seen that technique before. What do you do for IE7-8, serve a PNG?

Jon Tan

All good points. There is much to consider.

With reference to how many of the icons we commonly use are mapped in unicode, I’d love to see a comparison between common icons and existing unicode symbol code points as well as the newish transport and map symbols. I have a completely unsubstantiated feeling that the coverage is not bad at all. :)


Yeah I concur on the <b> thing… Plus the b tag literally yells at screen readers. And is outdated.

Otherwise interesting article, good food for thought! If you are up for creating a font. :)

David Bushell

@Jon Hicks — thanks for the reply, I can certainly see it as an option in some circumstances, but then SVG is also scalable and there are plenty of vector graphics available too, so I don’t think either technique could call an advantage in that respect.

IE7-8 support is tricky, but yes a PNG fallback. I think conditional comments with .oldie on the <html> element would be best but that’s ignoring Firefox 3.6 etc. Testing for SVG support with JavaScript is another way, but then the PNG fallback is downloaded before SVG is detected. You could do it the other way around and default to SVG, only applying a PNG if support is not detected.

Difficulty comes with relative sizes when the background-size property is not supported. That’s more of an issue with my sprite example and not specifically SVG, though you could argue web fonts work better in that example.

There are issues with both options but for most circumstances and certainly in the near future I’d say SVG has the upper hand.

One concern I really have with web font icons is when clients say they “don’t like” a particular icon — always happens! Suddenly you have to edit a font or find a new one. That could be a nightmare. Editing a vector graphic is a tad easier for most people.

Harry Jones

We’ve been using this technique to great effect on We designed a custom font file in order to cut down on file size and have full control over the symbols we use.

The biggest drawback for us has been rendering and aliasing issues at small sizes. The vector icons simply don’t look as crisp as their bitmap equivalents.

The data attribute tip and the idea of using the Unicode Private Use Area area are good ideas – thanks for the tips.


is @font-face supported by IE9? I’ve been working on a site recently and trying to avoid using images for icons. @font-face works fine for Chrome and FF but displays characters instead of symbols in IE8 and 9.

Also, what is the fallback technique you guys are using in the case of older IE versions?


Jon Gibbins

@Luke / @Sheila: Since the definition of the <b> element changed in HTML5 (it has become a way to mark “stylistically offset” text), it seems like a good fit in this case.

In my experience, no modern screen reader is affected by <b>, <i>, <strong> or <em> with normal settings. Older screen readers may have announced <strong> and <em> elements, but in latest versions of JAWS you needs to be in Proofreading mode for these elements to affect the speech output. While I think this is wrong – I’d expect at least <strong> or <em> to affect the output by default – I don’t think it would ever be right for <b> elements to effect speech output, HTML5 or otherwise. The <i> element is a different matter, since it can be used to indicate a change in language in HTML5.

Liam O'Leary

Using the @font-face method sounds good, but like someone else’s comment, aliasing on certain browsers and at smaller sizes is poor (depending on the font files).

I find that using HTML entities works better for websites that need a hand full of icons.

However if you’re creating a web app and need lot’s of custom icons then this is probably the best method.


The only Problem I see, its almost impossible to hide those characters from blind people, there is a Interesting stackoverflow* question about it. (@JON GIBBINS)

Great article by the way!

*( )


…Well, kinda academic approach, I think. The certain icon character is defined in CSS where it is displayed as ascii. Nice idea, though.


I have effectively solved the problem with screen readers. My Icon-Font Generator now offers an option for assigning your icons to the “Supplementary Private Use Area” of the Unicode. Watch this short video demo to see Apple’s VoiceOver in action. You can see that VoiceOver does not read any extra letters. With this update, IcoMoon is the first, and the only icon font out there that is fully compatible with screen readers. You can download a free version if you are interested.

Peter Uppington

Very interesting use of web fonts!

But whenever I print a page which uses them, my default local font is always used.

Should I take your fine article and confine your great advice to the online world only, or is there something I don’t know, that would allow for successful printing?

Yes, print is a waste of paper but, like it or not, people still like the printed thing. Some of the time!

If you are interested, IE8 prints web fonts perfectly, but Chrome and Firefox 8 do not.

Gilles Gallico

I am really impressed by this technique I didn’t know. Combining vector images for SEO purposes (in order to appear in Google Images for example) and icon fonts seems to be the best strategy. Thank you for the tip.

Daniel Genser

Really like this method a lot. It does have drawbacks, but I’m in favor of it (at least for the projects I’m working on at the moment).

I think @keyamoon deserves a shoutout, too, for his work on IcoMoons. His font generator which allows you to choose from his 300+ icons to create a customized kit and map it to Supplementary Private Use Area of Unicode is pretty sweet.

Just bought it today and is working great for our use.


The correct place to put the characters are Unicode Private Use Area (PUA) on positions U+E000 to U+F8FF (you have 6,400 code locations) on the Basic Multilingual Plane.
You also have PUAs on Plane 15 and Plane 16.

And, there are some icons here and there, like dignbats on positions U+2700 to U+27FF, and emoji, on positions U+1F30x to U+1F5Fx.

Joseph Wain (of Glyphish fame) evaluated creating a font, but it was deemed too difficult to maintain. (

I’m considering doing something like this for my personal use.


Very nice technique, hadn’t seen the data- method before! But the screenreader problem is fairly serious.

Also the demo page isn’t working on my Android Gingerbread browser, although webfonts are supported ( works at least) so I just see the original characters ($, k, t etc.)

Both make me wonder: couldn’t they have put their new characters in some far-out character area? Aren’t there areas of unicode reserved for weird symbols?

I know that you’d then have to escape the unicode to use it in “content”, but presumably it would fail back to a blank rather than a recognised but confusing character?

Impress us

Be friendly / use Textile