Barrierefreie Komponenten · Medien

Icons & SVGs barrierefrei einbinden

Icons sind klein, aber barrierefrei überraschend tückisch – vor allem, weil sie zwei völlig verschiedene Rollen spielen können. Manchmal sind sie reine Deko neben einem Text, manchmal tragen sie die Bedeutung allein, etwa als einziger Inhalt eines Buttons. Die richtige Auszeichnung hängt komplett davon ab, welche der beiden Rollen ein Icon gerade hat.

Die Leitfrage ist dieselbe wie bei Alt-Texten: Geht ohne das Icon Information verloren? Wenn nein, verstecken. Wenn ja, beschriften.

Dekoratives Icon: verstecken

Steht neben einem Icon ohnehin ein Text, der dieselbe Aussage trägt, ist das Icon dekorativ. Es wird vor assistiver Technik versteckt, damit es nicht doppelt angesagt wird:

<a href="/download.pdf">
  <svg aria-hidden="true" focusable="false" width="20" height="20">…</svg>
  Download (PDF)
</a>

aria-hidden="true" nimmt das SVG aus dem Accessibility-Baum, focusable="false" verhindert, dass es in manchen Browsern fälschlich fokussierbar wird. Diese Kombination setze ich an jedes rein schmückende Inline-SVG – sie ist quasi mein Standard-Snippet.

Bedeutungstragendes Icon: beschriften

Steht ein Icon für sich – ohne begleitenden Text –, braucht es einen zugänglichen Namen. Am verlässlichsten gelingt das mit role="img" und aria-label:

<svg role="img" aria-label="Erfolgreich gespeichert" focusable="false" width="20" height="20">

</svg>

Alternativ kann ein <title> als erstes Kind des SVG dienen, per aria-labelledby verknüpft. In der Praxis ist mir role="img" plus aria-label aber lieber, weil es weniger Fallstricke hat und browserübergreifend zuverlässiger funktioniert.

Der Klassiker: der Icon-Button

Der häufigste Fehler überhaupt ist der Button, der nur ein Icon enthält und sonst nichts – ein Lupensymbol, ein Hamburger, ein „ד. Für das Auge ist klar, was gemeint ist; ein Screenreader sagt aber nur „Schaltfläche”, ohne Namen. Die Lösung: Der Button bekommt den Namen, das Icon wird versteckt:

<button type="button" aria-label="Suche öffnen">
  <svg aria-hidden="true" focusable="false" width="24" height="24">…</svg>
</button>

Eine ebenso gute Variante ist sichtbar versteckter Text im Button (.visually-hidden) statt aria-label – der Vorteil ist derselbe wie bei Labels: echter Text, der mitübersetzt wird. Wichtig ist nur das Prinzip: Der Name gehört ans Bedienelement, nicht ans Icon.

SVG als <img> eingebunden

Bindest du ein SVG nicht inline, sondern über <img src="…"> ein, gelten die ganz normalen Bildregeln: ein alt, das die Bedeutung beschreibt, oder ein leeres alt="" für Deko. Das ist dann kein SVG-Spezialfall mehr, sondern Alt-Text-Handwerk.

<img src="diagramm.svg" alt="Umsatzentwicklung 2025: stetiger Anstieg" />
<img src="welle.svg" alt="" />

Icon-Fonts: dasselbe Prinzip

Bei Icon-Fonts (das Symbol entsteht aus einem Schriftzeichen) ist die Gefahr, dass Screenreader das zugrunde liegende Zeichen vorlesen. Auch hier: das Icon-Element per aria-hidden="true" verstecken und den Sinn über echten Text liefern. Ich greife heute meist zu Inline-SVG statt Icon-Fonts – aber wo Letztere im Einsatz sind, ist die Regel die gleiche.

Häufige Fehler

  • Icon-Button ohne Namen. Der häufigste Fehler – „Schaltfläche“ ohne jeden Hinweis, was sie tut.
  • Dekoratives Icon nicht versteckt. Wird zusätzlich zum Text angesagt und nervt.
  • Name am Icon statt am Button. Der zugängliche Name gehört ans Bedienelement.
  • focusable vergessen. Manche Browser machen SVGs sonst fokussierbar, was zusätzliche, leere Tab-Stopps erzeugt.
  • Bedeutung allein in der Farbe oder Form. Ein rotes Symbol ist kein Ersatz für einen Namen – siehe auch Farbkontraste.

Häufige Fragen

aria-hidden oder leeres alt – wann was?

alt="" ist für <img>-Bilder, aria-hidden="true" für Inline-SVGs und andere Inline-Elemente. Beide erreichen dasselbe Ziel – „bitte überspringen“ –, nur für unterschiedliche Einbindungsarten.

Reicht ein <title> im SVG nicht aus?

Es kann funktionieren, ist aber empfindlicher: Der <title> muss das erste Kind sein und sauber per aria-labelledby verbunden werden. role="img" mit aria-label ist robuster – deshalb ist es meine Standardwahl.

Muss ich jedes dekorative Icon einzeln verstecken?

Ja, jedes Inline-SVG, das Deko ist, bekommt aria-hidden="true". Das klingt nach Fleißarbeit, ist aber meist ein Snippet in der Icon-Komponente, das man einmal richtig setzt.

Fazit

Ob ein Icon Deko oder Bedeutungsträger ist, entscheidet alles: Deko wird mit aria-hidden="true" (plus focusable="false") versteckt, ein bedeutungstragendes Icon bekommt role="img" und aria-label. Beim Icon-Button gehört der Name immer ans Bedienelement, nie ans Symbol. Mit diesen drei Mustern sind die allermeisten Fälle abgedeckt – und der berüchtigte namenlose Icon-Button gehört der Vergangenheit an.