Dingbat Webfonts: Great potential, but we see (and hear) accessibility issues

April 2020 note: Hi! Just a quick note to say that this post is pretty old, and might contain outdated advice or links. We're keeping it online, but recommend that you check newer posts to see if there's a better approach.

While working through initial ideas for the forthcoming jQuery Mobile framework, we were looking for ways to decrease page weight and image requests, and did some experimenting with using a custom dingbat font (crafted with the excellent FontStruct editor) to enable rich, vector-based icons for the mobile UI components that could be enhanced even further with CSS. Unfortunately, support for CSS @font-face (the web-standards-based mechanism for referencing custom fonts) on mobile is spotty at best.

But the idea of using fonts for icons excited us, and may perhaps prove to be a great solution for desktop browsers. For this reason, we were thrilled to see the release of Pictos, a beautiful dingbat webfont by Drew Wilson. The Pictos site includes several examples of the icons in play, and the results are stunning, particularly with various CSS3 styles applied, and while scaling the browser’s text size. However, dingbat fonts map visual symbols directly to standard keyboard characters, and this raises some concerns for accessibility.

We see some definite accessibility challenges with the solution, and tried several work-around solutions, which we’ll describe below.

It looks good, but how does it sound?

In our brief experiments, we found that using dingbat fonts introduce some accessibility issues. A dingbat font basically maps images to the standard character map, meaning when their used alongside content on a web page, sighted users will see an icon in place of certain alpha-numeric characters in the markup. However, for users on screen readers and other assistive devices, the base characters (capital and lowercase letters, numbers, and standard symbols) are still read aloud. For example, if a dingbat font replaces, say, the letter “A” with an arrow icon, a screen reader still reads aloud the actual letter, regardless of its icon appearance.

This would be slightly odd but not necessarily terrible for simple static content scenarios (say, decorative icons on section headers), but has the potential to become quite confusing in more functional sites and applications.</>

For example, consider the scenario of an ecommerce site that adds icons to its checkout and cart buttons. Even with the most careful mapping, some of the common icons will correspond to letters or numbers that might cause confusion. What if, for example, the shopping cart icon were mapped to the number “6”? The markup to create a button with a shopping cart icon alongside its text (in this case, a span wrapped around a “6” character) in a “Purchase” button could look something like this:.

<button type="submit">Purchase <span class="icon">6</span></button>

While a visual user may see that “6” replaced with a nice icon of a shopping cart, a screen reader user will hear “Purchase 6”, which is probably not what they intend to do, or what the site intends to say.

Possible solutions

While we’ve admittedly had little time to invest in this so far, we have explored a few techniques to either hide the dingbat text from a screen reader, or provide more meaningful context in its place. Here are some ideas we’ve come up with so far:

  • A meaningful title attribute. Applying a title of “image: shopping cart icon” communicates the visual experience in an audible manner, but may be a bit verbose. In brief testing, we found that this text was not read aloud in place of the “6”, but it may still be useful in an alternate implementation.
  • Using role="image". Applying a WAI-ARIA role attribute with a value of image may be the best approach, particularly combined with either a title attribute (above), or an aria-label to serve as alt text. In testing in VoiceOver however, this didn’t seem to prevent the text from being read aloud. Oddly, the image role wasn’t spoken either, which may be a VoiceOver bug, or possibly because we’ve placed it inside a form control.
  • Using the :before CSS pseudo-element This interesting idea is the proposed technique offered on the Pictos site. By placing actual meaningful content in the span and utilizing a CSS :before selector to add the icon text, we may end up with a similar experience to the title attribute idea proposed above. Unfortunately, in a test on VoiceOver, we found that it spoke the generated character aloud, reintroducing the original problem.
  • Using aria-hidden. Applying an ARIA attribute such as aria-hidden="true" may hide the text from being read aloud, which may be ideal if the icon itself is not essential to the experience. In brief testing on VoiceOver, the screen reader spoke “HTML content” when it encountered the span, which wasn’t really an improvement.
  • Using character entity equivalents We also attempted using unicode entities in place of alpha-numeric characters (such as a &#0054; in place of the “6”), but the letter was still spoken aloud as “6”.

Browser Support Concerns

Of course, several of these solutions require an ARIA-capable screen reader, so a bullet-proof approach would likely require a combination of ARIA attributes and attributes from earlier standards, such as title.

Also, sighted users with browsers that don’t support webfonts will likely see a non-icon character (such as an actual “6”), because the browser will simply render the character in the next available font in its stack. This issue is of particular concern on mobile devices, as many lack support for webfonts, but also on many older desktop browsers as well.

Help us figure this out!

We’d be interested in hearing your thoughts on using fonts this way, as well as suggested approaches to making them accessible.

Also, thanks to Jason Santa Maria for the inspiration to post this article!

All blog posts