Update: 2011-11-22
Chris Coyier wrote a demo of what you can do with icon fonts and it’s rather compelling. Chris has included a rebuttal of the “oh yeah but it’s not accessible” argument but sadly his answer only addresses a fraction of the problem. So I’d like to expand on that.
Disclaimer: I know more about web accessibility than most CSS coders, but much less than accessibility experts. I’m writing this partly to get answers and feedback. :)
Most web developers who have heard about accessibility tend to think that accessible code is code that works decently in screen readers. Not quite. Screen readers are just one type of assistive technology (and more broadly one type of user agent). Some people will use other assistive technology, or they will use regular web browsers but use some of their features which we’re not used to design for.
text-indentChris used this HTML code as an example:
<a href="#" class="icon icon-replace icon-check">Check</a>
There is no accessibility issue with this HTML code (though if it’s a button rather than a hyperlink, using the button element would be better). But what about the CSS?
Chris does two things: generate a pseudo-element to show the icon, and hide the original text with a negative text-indent (a technique that doesn’t hide the text from screen readers). Here’s a couple of situations where it could break:
I’m probably forgetting a few use cases. Anyway, what Chris’ solution does is handle one such case: screen reader use. Basically, it’s an inaccessible solution that comes with an accessibility fix for one use case. Is that enough? I don’t know.
If we go back to Chris’ example, here’s what the resulting DOM looks like (pardon my pseudocode):
<a>
<before>✔</before>
<text>Check</code>
</a>
Now compare it with this HTML construct:
<a>
<img src="check.png" alt="Check">
</a>
When we use the img element, the user agent knows that the picture and the text are equivalent (and by default the picture is preferred). It’s able to show the picture, but also to replace it with the text for any sensible reason (e.g. user asked for this behavior, or the picture did not load).
When we use common image replacement techniques, including the smart ones, the user agent doesn’t know what’s the relation between the text content and a CSS pseudo-element or background. This is not even a “CSS is for decoration” issue. It’s a “your code lacks semantic information” issue, with two consequences:
If you’re keeping a visible text label, and just want to add an icon next to it, by all means do use CSS backgrounds or an icon font.
I’m not sure. Maybe something with SVG, maybe something with the abbr element, but I wouldn’t bet on it.