QuestionsAccessibility

Accessible SVG, icons & complex images

Images & SVGMediumAccessibility

How do you make inline SVG icons and complex graphics accessible? What about icon-only buttons?

What it tests

Naming/hiding inline SVG correctly and handling icon-only controls and complex images.

Approach & answer

Inline SVG has no alt attribute, and browser/AT support for its internal semantics is inconsistent, so you name or hide it explicitly. DECORATIVE svg (an icon next to text that already says the same thing) should be removed from the tree: aria-hidden="true" plus focusable="false" (the latter stops old IE/Edge from tabbing into it). MEANINGFUL standalone svg should get role="img" and a name via aria-label (or a <title> element referenced by aria-labelledby) — role="img" collapses the SVG's internal shapes so the name is announced as one graphic rather than reading every <path>. ICON-ONLY BUTTONS are the highest-frequency bug: <button><svg…></button> with no text is a nameless button. Fix by naming the BUTTON (aria-label="Close") and hiding the decorative icon inside it (aria-hidden), or include visually-hidden text. For a COMPLEX image (an infographic, a data-dense chart), a short alt/label can't carry it — provide a longer text alternative nearby (a caption, an adjacent description, or a data table conveying the same information), and keep the short name as an entry point. General rule: the icon is decoration; the CONTROL or the graphic's MEANING is what needs the name. And don't forget: an SVG conveying state (a filled vs empty star rating) needs that state in text/ARIA, since colour and shape alone won't reach everyone.

Use this technique when

Adding inline SVG icons; naming icon-only buttons; giving complex graphics a real text alternative.

Code

<!-- Decorative icon beside text: hide it from the tree -->
<button>
  <svg aria-hidden="true" focusable="false">…</svg>
  Delete
</button>

<!-- Icon-only button: name the BUTTON, hide the icon -->
<button aria-label="Close dialog">
  <svg aria-hidden="true" focusable="false">…</svg>
</button>

<!-- Meaningful standalone graphic: role=img + name -->
<svg role="img" aria-label="Company logo">…</svg>

<!-- Complex image: short name + longer description nearby -->
<img src="flow.png" alt="Signup funnel (described below)">
<div id="flow-desc"><p>Visitors → 40% sign up → 12% activate…</p></div>

References