Summary

Icon fonts are vector graphics that are included in the content using the CSS content property on a before or after pseudo-class selector. As with regular fonts, icon fonts are scalable and can be styled using CSS, unlike images. They also have the benefit that they remain visible in high contrast on Windows, unlike CSS background images. The biggest drawback from an accessibility point of view is that they won't work if a user's user-defined style sheet overrides the font-family property.

Author: Gez Lemon

Icon fonts

Icon fonts are generally good from an accessibility point of view if used correctly, as they are scalable and remain visible in high contrast on Windows. Using icon fonts that use the Private Use Area of Unicode, such as IcoMoon, work well with assistive technologies. If the icon is purely visual, then the aria-hidden attribute should be used on the element to ensure it is not revealed to assistive technologies.

Using aria-hidden with a decorative icon
<div class="icon-star" aria-hidden="true"></div>

If the icon is used to convey information, then it should contain a text alternative that may be hidden visually if required, but available for assistive technologies.

Providing a text alternative for the icon font
<div class="icon-mail"><span class="context">Mail</span></div>

The text that provides the context for the icon can then be hidden visually with CSS so that it's still available to screen reader users.

Hiding context visually with CSS
.context {
  position: absolute !important;
  clip: rect(1px, 1px, 1px, 1px);
  padding: 0 !important;
  border: 0 !important;
  height: 1px !important;
  width: 1px !important;
  overflow: hidden;
}

To work, icon fonts depend on the font-family property in CSS. If the icon is purely decorative, being overridden by the user's style sheet isn't an issue. When an icon font is used to convey information, such as the graphic for a button element, it means the visual representation will be missing, which is a serious issue.

User-defined style sheets

There isn't much data available about how widely user-defined style sheets are used by people with disabilities. It's probably fair to say that the number is low due to lack of awareness, but the benefits can be great for people with vision impairments or reading difficulties. I asked my colleague (and occasional running buddy) David Sloan if he was aware of any research, and he pointed me to a study about understanding users' text requirements that analyses 203 user-defined style sheets from 25 people.

For readability, it seems reasonable to assume that the font-family property is likely to be overridden. The study shows that font-family is the fourth most common global property, and the second most common element-level property to be overridden in the user's style sheet. Although the number of people using user-defined style sheets for accessibility might be small, they shouldn't be overlooked.

Determining if font-family is honoured

One solution to the problem is to use a script to determine if font-family is honoured. If the property is honoured, then use icon fonts; otherwise, only use them if they're decorative, and use an alternative method where they provide visual information to ensure it's usable by someone using a user-defined style sheet. The following is an example of a function that could be used to check if the font is honoured:

Update: Thanks to Federico Brigante for pointing out that this script doesn't work with Chrome. I tested the script with a user-defined style sheet in IE and Firefox, and it works correctly, but sadly doesn't work with Chrome. In his comment, Federico suggested another technique that could be used to detect whether a font is available.

Function to check if font-family is honoured
function checkFont(strFamily) {
  var objDiv = document.createElement('div');

  objDiv.style.fontFamily = strFamily;
  objDiv.appendChild(document.createTextNode('FONT TEST'));

  if (window.getComputedStyle) {
      return window.getComputedStyle(objDiv, null).getPropertyValue('font-family') === strFamily;
  }

  return objDiv.currentStyle.fontFamily === strFamily;
}

The function can then be called with the appropriate font-family property:

Using the checkFont function
var bHonoured = checkFont('icomoon');

Adopting this technique means the page gets the benefit of using icon fonts, but also ensures that people using user-defined style sheets to improve readability for accessibility also get the information.

Useful resources

Category: Accessibility.

Comments

  1. [icon-fonts-user-defined-stylesheets.php#comment1]

    checkFont() doesn't seem to work: http://codepen.io/anon/pen/HIKDq
    Chrome reports all are missing, Firefox reports all available.

    .getPropertyValue() reports the entire font stack as it was specified, not just the valid font.

    Try this in the console: window.getComputedStyle(document.body, null).getPropertyValue('font-family')

    There is not 100% reliable way to detect whether a font is available, but this seems to work: http://www.lalit.org/lab/javascript-css-font-detect/

    Posted by Federico Brigante on

  2. [icon-fonts-user-defined-stylesheets.php#comment2]

    Hi Federico,

    Thank you for your comment. I tested it with IE and Firefox, but hadn't tested with Chrome. I've updated the article to include your comment about the technique not working with Chrome, and the alternative technique you've linked to.

    Thanks,

    Posted by Gez on

  3. [icon-fonts-user-defined-stylesheets.php#comment3]

    Hi Gez,

    Is it necessary to add the aria-hidden="true" attribute for decorative elements/icons too? As these elements don't have any text within them, wouldn't screen readers ignore them by default?

    Posted by Bhavik on

  4. [icon-fonts-user-defined-stylesheets.php#comment4]

    Even when icon fonts use the Private Use Area of Unicode, if the element has no content it should use aria-hidden to ensure the blank element isn't exposed to assistive technologies.

    Posted by Gez Lemon on

Add your Comment

Please read the comment guidelines before posting your comment. Email addresses are not displayed.