icons and emoji accessibility

December 10, 2022 - Reading time: 4 minutes

I recently discovered about Font Awesome and Unicode emojis. I thought: this a great way to have images without actually hosting them! As I'd like my projects to require a minimum of ressources that may suit my needs. But wait. I'd like these projects to also be as accessible as possible. How can you achieve that when this HTML element (for font awesome) and character (for Unicode emoji) are not HTML images (<img>) and therefore cannot have an alt attribute containing the relevant alternative text?

Let's dig this out!

Font Awesome

Well, for Font Awesome, the answer is on their website, they have a dedicated section! It is beautifully sumed up on Upyouray11.com so I'll just try to sum up the sum up, so to have a reference somewhere on my own blog.

Decorative image

Hide it from assistive technologies with aria-hidden attribute, value true.

<i aria-hidden="true" class="fas fa-car"></i>

Action image

Hide the icon itself but indicate the link purpose (menu, home, cart...) with aria-label attribute on the action HTML element

<a href="/" aria-label="Home">
  <i aria-hidden="true" class="fas fa-home"></i>
</a>

Meaningful images

Hide the alternative text in a span element via CSS so it's dedicated to assistive technologies

HTML would be

<i aria-hidden="true" class="fas fa-plant" title="Vegetarian"></i>
<span class="screen-reader-only">Vegetarian</span>

Note that we are adding a title attribute to help sighted mouse users

CSS would be

.screen-reader-only {
  position: absolute;
  left: -10000px;
  top: auto;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

Unicode emojis

Decorative image

Hide it from assistive technologies with aria-hidden attribute, value true in an additionnal span element:

<span aria-hidden="true">&#x1F4D6;</span>

Other images

Nest the emoji into a span element and give it a role attribute, value img and the alternative text in aria-label attribute's value:

<span role="img" aria-label="open book">&#x1F4D6;</span>

Now, let's apply this in this blog's contents!