Icons and links

Icon links and icon buttons

We’ve talked about the use of icons on your page. There are different ways to implement icon links and icon buttons. We could use SVG, in our case we’ll stick to a web font. In the end it doesn’t matter where the icon comes from, it’s about how it’s used on the site.

Simple approach

In its simplest form we should use an unused element such as an <i>, apply some class selectors and throw it into a link.

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

In this case you’ll see the icon of a house. With the aid of some CSS you can create a :hover-state and your designer will be happy. It works, sure, but there are some things you should bear in mind:

  1. The click area might be too small
  2. Not everyone will understand the icon
  3. The link has no meaning at all. Screen readers will just read link.

The last bulletpoint could be fixed by adding a aria-label - but as mentioned earlier this is just a crutch. So let’s have a look at another solution.

Enhance icon with text

This is the easiest way to make your icon links (and buttons) accessible. Just place rock-solid copy next to the icon within the link.

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

VoiceOver will read link, home. ChromeVox, on the other hand, will read home, internal link and Narrator will read Home, link, value: URL comma read-only. In all three cases the user gets an understanding of what this link is for. All sighted users will get an idea of what it’s about, too. Mouse users also enjoy a bigger click area. This will also help users on a touch device.

Visual but accessible icon

If— for some reason—your design department is not willing to take the above-described route, you can still hide the text with our .visible-hidden class selector. That way all sighted users will only see the icon, but it is accessible via screen readers. However, there remains the issue of not understanding the icon and/or the smaller click/touch area.

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

VoiceOver will read internal link, home and ChromeVox home, internal link and Narrator still reads Home, link, value: URL comma read-only. So nothing has changed on this level.

Of course you can apply this technique to a button as well:

<button type="submit">
 <i class="fas fa-search" aria-hidden="true"></i>
 <span class="visually-hidden">Search</span>

Video example

This video shows three different ways to code a link with an icon. Read out by VoiceOver, ChromeVox and Narrator.

Use aria-hidden

Did you wonder why there is an aria-hidden applied to the icons? That's because the font icons don’t get recognized by e.g. VoiceOver’s rotator. In rotator there will be a question mark in front of the link text. Whereas as soon as we’ll apply the aria-hidden to the icon we’ll end up with this:

screenshot of two links - one with aria-hidden and the other without
The first link doesn't have an aria-hidden, so VoiceOver's rotator will get confused and show a question mark. It looks broken. That's why the second links contains an aria-hidden. The rotator will only display the links's name.