SVG and Emoji Icon Accessibility

SVG and Emoji Icon Accessibility

Let's go through some tips on accessible iconography: SVGs, HTML entities, and emoji!

SVG

We all know SVG icons are fantastic for so many reasons (such as scalability, their ability to animate, and are able to flex and respond to a viewport's requirements) but how do we make sure they're accessible?

Let's take a look at a few different scenarios where SVG embedded within HTML might be used and how to ensure they are accessible for people using assistive technology.

Informative or decorative?

Like images on the web using the img element, we need to determine if an SVG is informative (its presence is worthy of adding content to the current context) or is purely decorative (adding a bit of eye candy for sighted users, but not important enough to warrant a text alternative.)

Informative

In the case of an SVG being informative, there exists a pattern which renders the SVG and its content consistently across modern browsers and screen readers. This pattern consists of three key items:

  • The role attribute applied to the SVG element itself, with a value of "img" – ensures assistive technology announces its role as, "image"
  • The aria-labelledby attribute on the SVG with its value set to match the id of the SVG title element – ensures assistive technology consistently announces the value in the title
  • The SVG title element with its content set to the accessible name of the SVG
<svg aria-labelledby="icon-title" role="img">
  <title id="icon-title">SVG image description</title>
  <!-- Other required elements... -->
</svg>

With these items now in place, all browser + screen readers will accurately announce the SVG content as:

"SVG image description, image"

When to apply this

A few instances where this would be used include:

  • An SVG being used as a stand-alone logo or image adding content to a page
  • A social media icon embedded within a link with no other text
  • A lone icon embedded within an action button with no other text
  • A point in a graph or chart

When the SVG is the only piece of content inside an a or button element, this pattern serves as the element's accessible name, giving context to the purpose of the currently focused element.

Decorative

A decorative SVG exists only to serve as a visual aid for sighted users. In this instance we need to setup the SVG to be "hidden" from screen reader users as announcing the presence of a non-content item would only be a nuisance.

Just like its informative cousin, the decorative SVG requires a few extra attributes:

  • The role attribute with a value of "presentation" – helps to strip away any semantic meaning
  • The aria-hidden attribute with its value set to "true" – hides the SVG from assistive technology
  • The focusable attribute set to "false" – this helps to avoid an Internet Explorer bug where if the SVG were embedded within a focusable element, such as an a or button, it would cause an extra tab-stop to occur
<svg role="presentation" aria-hidden="true" focusable="false">
  <!-- Other required elements... -->
</svg>

With these attributes set in place, the SVG element will be completely removed from assistive technology.

When to apply this

A few instances where this would be used include:

  1. An SVG image which serves as a visual aid only
  2. A social media icon embedded within a link with visual text
  3. A lone icon embedded within an action button with visual text

When the SVG is alongside related text content, this pattern serves to remove the SVG from assistive technology, avoiding any unnecessary announcements.

Hiding entity characters

It's not uncommon to have a design requirement be made to include an arrow or plus/minus imagery inside of a link or button. For reasons such as performance and including crisp imagery on a variety of devices and screens, this is usually accomplished by including an HTML entity character. However, in doing so, this pattern may have introduced an accessibility issue.

What issue, you may ask? Entity characters have their own, built-in semantics and accessible name. When a screen reader comes into contact with an entity character, it is announced like any other piece of text. Having the extra content announcement, however minor, could lead to a confusing user experience for some.

In the context of the example of adding an arrow icon to a button, the entity icon is purely decorative. In the same light as removing an alt text value from an image that's been deemed as "decorative" in order to hide from screen readers, the same treatment should be applied to entity characters.

Let's review a few common techniques on adding an entity character and making sure it is ignored by assistive technology.

Using CSS

A common CSS pattern for including an arrow styled icon within a button element is using a CSS pseudo element. The following code should achieve what we're looking for:

.btn--continue:after {
  content: ' →';
}

This code will add the arrow icon to each instance of the matched selector, however, the character will be announced by a screen reader. This is not ideal. (There were plans for the CSS3 specification to allow CSS to hide content from assistive technology. Sadly, work on the CSS Speech Module has been discontinued.)

Directly in HTML

Let's review another pattern, placing the arrow icon directly within HTML:

<button class="btn btn--continue">Continue →</button>

Again, this code will add the arrow icon to each instance of the button element, however, the character will be announced by a screen reader.

Wrap with aria-hidden

The method of making an entity icon hidden from screen readers and other assistive technology, ie., setting it as decorative, is to wrap the icon itself with an aria-hidden element.

<button class="btn btn--continue">
  Continue
  <span aria-hidden="true">→</span>
</button>

With this in place, the arrow icon will be ignored by assistive technology and only the vital information of, "Continue" will be announced.

Accessible emoji

Emoji are a great tool for quickly expressing an emotion or action via icons. However, when it comes to emoji's and accessibility, what's displayed visually may not come across the same for someone using assistive technology.

Take for instance the common phrases, "I ❤️ you" – announced as, "I red heart you." This isn't exactly the correct meaning behind this message. Let's make this emoji more friendly to screen reader users.

In order to render the content as one may expect, we can wrap the emoji character with an HTML container element and add some attributes:

  • Wrap the emoji with a span element since it has no semantic meaning and is styled inline by default
  • Add the role attribute, setting its value to "img" in order to announce the emoji as an image
  • Add the aria-label attribute, setting its value to the expected text to be announced (this is similar to setting an alt attribute on an actual image element)
<p>
  I
  <span role="img" aria-label="love">❤️</span>
  you.
</p>

Now with this setup, screen readers will hear the message as intended!

Text and Icons

From a usability perspective, using icons and text together provides the most context for people to understand iconography. For some people, being able to recognize a consistently used icon is a quick way to gain context. For others (including people who might be using translation tools) text can be more helpful. For people with reading disabilities, the combination of text and icon can help reinforce concepts and provide reassurance. Icons that represent literal concepts or objects are always clearer than those that represent metaphors.

When using informative icons, always consider what text best describes them. Use the same text consistently in order for people to always understand the meaning of the icon. Icons should only be used alone when they represent a concept that is universally understood in the system. If an icon is used alone, a text equivalent is still needed for people who rely on screen readers or other text to speech tools.

Resources:

Back to blog