Inline SVG used for buttons and links

View the library of solutions.

The following findings have been updated based on tests done in December 2016. Find the test codepen page to do your own tests and review the table of screen-reader findings.

Why use SVG instead background image

SVG is preferable for icons over background images/sprites because if PC is in High Contrast Mode, SVGs are still visible. Background images are not rendered.

SVGs can be scaled to their parent container (as long as you don't set width and height to SVG).

Stay away from the svg title and desc elements

The SVG title and desc elements are currently still very problematic with most screen readers. Therefore I do not suggest using the svg title and desc elements for accessibility.

If we consider a nested image tag as the gold standard to be mimicked by the svg tag we should stay away from the svg desc or title tags. Use aria-label for the button and screen-reader-text for the link.

Nor do I suggest using role="img", assuming you want to mimic a nested image tag. Using role="presentation" gives a more consistent result.

Also, stay away from using aria-labeledby and aria-describedby. This causes repeating phrases.

Known issues:

Below are just some of the issues when using nested title and desc elements.

Problems with NVDA:

Problems with VoiceOver:

Preferred method:

I suggest trying to match the screen-reader output of a button or link with a nested image element.

Button example:


<button type="button" style="width: 50px; height: 50px;" aria-label="Reveal navigation">
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="00 0 90 90" role="presentation" focusable="false">
    <circle cx="45" cy="45" r="40" stroke="black" stroke-width="3" fill="red">
  </svg>
</button>
			

Link example:

search google

<a href="http://www.google.com/" style="display: inline-block; width: 50px; height: 50px;">
  <span class="screen-reader-text">search google</span>
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="00 0 90 90" role="presentation" focusable="false">
    <circle cx="45" cy="45" r="40" stroke="black" stroke-width="3" fill="blue">
  </svg>
</a>