Ressourcen · Nachschlagen

Snippet-Bibliothek

Diese Sammlung enthält die zwölf Muster, die in fast jedem Projekt gebraucht werden – vom Skip-Link über die visuell versteckte Beschriftung bis zur Live-Region. Jedes Snippet steht hier so kurz wie möglich, mit dem Stolperstein, an dem es beim Kopieren am häufigsten kaputtgeht.

Ein Snippet ist ein Startpunkt, keine Garantie. Gerade bei ARIA gilt: blind kopieren ist genau der Weg, auf dem schlechte Auszeichnung in die Welt kommt. Ich empfehle deshalb, jedes Muster einmal zu verstehen, bevor es ins eigene Projekt wandert – die ausführliche Begründung steht jeweils im verlinkten Artikel.

Das Wichtigste in Kürze

  • Neun von zwölf Snippets brauchen kein JavaScript und kein einziges ARIA-Attribut. Das ist Absicht: Nativ ist robuster.
  • .visually-hidden gehört in jedes Projekt. display: none und visibility: hidden sind kein Ersatz – sie nehmen den Text auch dem Screenreader.
  • Der Skip-Link muss der erste fokussierbare Link im DOM sein und beim Fokus sichtbar werden. Ein dauerhaft versteckter Skip-Link hilft niemandem.
  • Icon-Buttons brauchen einen Namen im Text, nicht nur ein title-Attribut. Das SVG bekommt aria-hidden="true" und focusable="false".
  • <details> und <dialog> bringen Tastaturbedienung und Zustand von Haus aus mit – inklusive Esc, Fokus-Falle und Backdrop beim modalen Dialog.
  • Live-Regionen müssen vor dem Einfügen des Textes im DOM stehen. Ein Container, der zusammen mit seiner Meldung erzeugt wird, bleibt stumm.
  • Fokus nie ohne Ersatz entfernen. outline: none ohne eigenen sichtbaren Stil verstößt gegen WCAG 2.4.7.
Eine Tabelle mit vier Zeilen und den Spalten Technik, visuell weg, im Accessibility Tree, fokussierbar und Ergebnis. Zeile 1, rot hinterlegt: display none oder das hidden-Attribut – visuell weg ja, im Accessibility Tree nein, fokussierbar nein; der Screenreader liest nichts. Zeile 2, rot: visibility hidden – gleiche Werte, nur bleibt die Lücke im Layout. Zeile 3, gelb: opacity 0 oder Schriftfarbe gleich Hintergrund – visuell weg ja, im Tree ja, fokussierbar ja; wird vorgelesen, erzeugt aber unsichtbare Tabstopps und beansprucht Platz. Zeile 4, grün: die Klasse visually-hidden mit einem Pixel Größe und clip-path inset 50 Prozent – visuell weg ja, im Tree ja, fokussierbar ja mit Sternchen; der Screenreader liest den Text, das Layout bleibt unberührt. Rechts daneben ein grün umrandeter Kasten mit drei Regeln: Text nur für Screenreader gehört in Zeile 4, Text für niemanden in Zeile 1, und Zeile 3 ist fast immer ein Versehen. Darunter der CSS-Code der Klasse visually-hidden.
Die drei häufigen Wege, Text zu verstecken, tun jeweils etwas anderes. Nur der vierte liefert Text für Screenreader.

Native HTML zuerst. Die meisten Snippets hier kommen ohne JavaScript und mit so wenig ARIA wie möglich aus. Warum das die robustere Wahl ist, steht unter Die erste Regel von ARIA.

Nur-für-Screenreader-Klasse (.visually-hidden)

Diese Utility-Klasse blendet Text visuell aus, lässt ihn aber für Screenreader lesbar – ideal für zusätzliche Beschriftungen, Sprungmarken-Titel oder Statusmeldungen.

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
}

Warum so umständlich? Jede der Deklarationen hat einen Grund: Die Größe von einem Pixel verhindert, dass Browser das Element als leer wegoptimieren; clip-path schneidet den sichtbaren Inhalt weg, ohne ihn aus dem Accessibility Tree zu entfernen; white-space: nowrap verhindert, dass langer Text im Ein-Pixel-Kasten umbricht und dadurch wieder Platz beansprucht.

Stolperstein: Enthält der versteckte Bereich einen Link oder Button, entsteht ein unsichtbarer Tabstopp. Für solche Fälle gibt es die Variante .visually-hidden-focusable, die das Element bei Fokus wieder einblendet – genau das tut auch der Skip-Link unten.

Der erste fokussierbare Link der Seite, normalerweise unsichtbar, bei Tastaturfokus sichtbar. Er springt direkt zum Hauptinhalt und erspart Tastatur-Nutzenden, sich durch die komplette Navigation zu tabben. Diese Website nutzt genau dieses Muster.

<a class="skip-link" href="#inhalt">Zum Inhalt springen</a>
<!-- Header / Navigation -->
<main id="inhalt" tabindex="-1">…</main>
.skip-link {
  position: absolute;
  top: -3rem;
  left: 0.5rem;
  padding: 0.5rem 1rem;
  background: #fff;
  color: #000;
  transition: top 0.15s ease;
}
.skip-link:focus {
  top: 0.5rem;
}

Warum das tabindex="-1" am <main>? Ohne es setzen manche Browser den Fokus nach dem Sprung nicht auf das Ziel, sondern lassen ihn am Link – der nächste Tab landet dann wieder in der Navigation. Mit dem Attribut wird <main> programmatisch fokussierbar, ohne in die Tab-Reihenfolge zu geraten.

Stolperstein: Ein Skip-Link, der nur per opacity: 0 versteckt ist, bleibt anklickbar und erzeugt Verwirrung; einer mit display: none ist gar nicht erreichbar. Details unter Skip-Links.

Icon-Button mit zugänglichem Namen

Ein Button, der nur ein Icon zeigt, braucht trotzdem einen Namen. Das SVG bekommt aria-hidden, der Name kommt als visuell verstecktes <span>.

<button type="button" class="icon-button">
  <svg viewBox="0 0 24 24" width="24" height="24" aria-hidden="true" focusable="false">
    <path d="M3 6h18M3 12h18M3 18h18" fill="none" stroke="currentColor"
          stroke-width="2" stroke-linecap="round" />
  </svg>
  <span class="visually-hidden">Menü öffnen</span>
</button>

Der Name im Text ist einem aria-label vorzuziehen: Er wird von Übersetzungswerkzeugen erfasst, ist im DOM sichtbar und lässt sich mit Sprachsteuerung ansprechen. focusable="false" am SVG verhindert einen zusätzlichen Tabstopp in älteren Edge-Versionen.

Stolperstein: Ändert der Button seinen Zustand – etwa von „Menü öffnen“ zu „Menü schließen“ –, muss der Text mitwandern, nicht nur das Icon. Mehr unter Icons & SVGs und Buttons vs. Links.

Sichtbarer Fokus mit :focus-visible

Der Fokusrahmen ist die Anzeige, wo man sich befindet – ihn zu entfernen, ist der häufigste Verstoß gegen die Tastaturbedienbarkeit. Mit :focus-visible bekommt man einen deutlichen Rahmen für Tastatur-Nutzung, ohne bei Mausklicks einen Rahmen zu zeigen.

:focus-visible {
  outline: 3px solid #1d4ed8;
  outline-offset: 2px;
  border-radius: 2px;
}

Stolperstein: outline: none an einer allgemeinen Regel wie *:focus löscht den Rahmen überall – auch dort, wo kein Ersatz definiert ist. Wenn eine Komponente einen eigenen Fokus-Stil braucht, dann lokal und mit sichtbarem Ergebnis.

Akkordeon ohne JavaScript (<details>)

Für einfaches Auf- und Zuklappen braucht es kein Skript und kein ARIA – <details> und <summary> bringen Tastaturbedienung und Zustand von Haus aus mit.

<details>
  <summary>Versand &amp; Lieferzeit</summary>
  <p>Wir liefern innerhalb von 2–4 Werktagen innerhalb Deutschlands.</p>
</details>

Stolperstein: Ein <summary>, das eine Überschrift enthalten soll, braucht die Überschrift innerhalb<summary><h3>Titel</h3></summary> – und nicht darüber. Und Inhalte in einem geschlossenen <details> sind für die Seitensuche im Browser unsichtbar; bei wichtigen Inhalten ist das ein Argument dagegen. Wann es reicht und wann nicht: Akkordeons.

Dialog mit <dialog>

Das native <dialog> mit showModal() bringt Fokus-Falle, Schließen per Esc und einen Backdrop von selbst mit – Dinge, die man sonst mühsam nachbaut. Das <form method="dialog"> schließt den Dialog beim Absenden.

<button type="button" data-dialog-open="hinweis">Hinweis öffnen</button>

<dialog id="hinweis" aria-labelledby="hinweis-titel">
  <form method="dialog">
    <h2 id="hinweis-titel">Cookies</h2>
    <p>Diese Seite nutzt nur technisch notwendige Cookies.</p>
    <button>Verstanden</button>
  </form>
</dialog>
document.querySelectorAll('[data-dialog-open]').forEach((btn) => {
  btn.addEventListener('click', () => {
    document.getElementById(btn.dataset.dialogOpen).showModal();
  });
});

Stolperstein: show() statt showModal() erzeugt einen nicht-modalen Dialog ohne Fokus-Falle und ohne Esc – ein häufiger Fehler beim Kopieren. Und nach dem Schließen muss der Fokus zurück auf das auslösende Element; das macht der Browser bei showModal() in aktuellen Versionen, aber nicht in jedem Szenario. Hintergrund: Dialoge / Modals.

Eingabefeld mit Label und Fehlermeldung

Jedes Feld bekommt ein echtes <label for>. Hilfetext und Fehlermeldung werden über aria-describedby verknüpft – beide IDs, durch Leerzeichen getrennt. aria-invalid setzt man erst, wenn ein Fehler vorliegt.

<label for="email">E-Mail-Adresse</label>
<input
  id="email"
  name="email"
  type="email"
  autocomplete="email"
  required
  aria-describedby="email-hilfe email-fehler"
  aria-invalid="true"
/>
<p id="email-hilfe">Wir nutzen die Adresse nur für die Bestellbestätigung.</p>
<p id="email-fehler" class="fehler">
  Bitte gib eine gültige E-Mail-Adresse ein (z. B. name@beispiel.de).
</p>

Stolperstein: Wird die Fehlermeldung erst im Fehlerfall ins DOM geschrieben, verweist aria-describedby bis dahin auf eine nicht existierende ID. Das ist unschön, aber harmlos – kritisch wird es umgekehrt: Steht aria-invalid="true" von Anfang an, ist die Angabe bedeutungslos. Mehr unter Labels & Beschriftungen und Validierung & Pflichtfelder.

Fehlerliste über dem Formular

Das zuverlässigste Muster für Formularfehler: eine Zusammenfassung mit Sprunglinks, die nach dem Absenden den Fokus bekommt.

<div id="fehlerliste" role="alert" tabindex="-1" hidden>
  <h2>Zwei Angaben fehlen noch</h2>
  <ul>
    <li><a href="#email">E-Mail-Adresse: Bitte gib eine Adresse mit @ ein.</a></li>
    <li><a href="#plz">Postleitzahl: Bitte fünf Ziffern eingeben.</a></li>
  </ul>
</div>

Ein Fokuswechsel auf diesen Container ist verlässlicher als jede Live-Region, weil die Ansage nicht vom Timing abhängt. Details unter Fehlermeldungen barrierefrei.

Eine Brotkrume ist eine geordnete Liste in einem benannten <nav>. Die aktuelle Seite ist kein Link, sondern Text mit aria-current="page".

<nav aria-label="Sie sind hier">
  <ol>
    <li><a href="/index.html">Start</a></li>
    <li><a href="/ressourcen.html">Ressourcen</a></li>
    <li><span aria-current="page">Snippet-Bibliothek</span></li>
  </ol>
</nav>

Stolperstein: Trennzeichen als Textzeichen im Markup werden mitgelesen – „Start Schrägstrich Ressourcen“. Sie gehören ins CSS. Warum <ol> und warum aria-current: Breadcrumbs.

Statusmeldung (Live-Region)

Wenn sich nach einer Aktion etwas ändert, ohne dass der Fokus springt – „gespeichert“, „3 Treffer“ –, gehört die Meldung in eine Live-Region.

<p id="status" role="status" aria-live="polite" class="visually-hidden"></p>
document.getElementById('status').textContent = 'Formular gespeichert.';

Stolperstein: Der Container muss schon im DOM stehen, bevor Text hineinkommt – wird er zusammen mit der Meldung erzeugt, bleibt es still. Und derselbe Text zweimal hintereinander wird nicht erneut angesagt; in solchen Fällen hilft ein kurzes Leeren des Containers. Wann polite, wann assertive: Live-Regionen.

Sprachwechsel im Text

Wenn mitten im deutschen Text ein englischer Begriff steht, den die Sprachausgabe falsch ausspricht, hilft ein lang-Attribut am umgebenden Element.

<p>Das Muster heißt <span lang="en">progressive enhancement</span>.</p>

Stolperstein: Das gilt für ganze Phrasen, nicht für Fachwörter, die im Deutschen etabliert sind – „Browser“ oder „Link“ brauchen kein lang. Und das <html lang="de"> am Dokumentanfang ist die Voraussetzung dafür, dass der Wechsel überhaupt eine Wirkung hat.

Datentabelle mit Beschriftung

Eine Tabelle braucht eine <caption> und echte Kopfzellen mit scope – dann kann ein Screenreader jede Zelle mit ihrer Zeilen- und Spaltenüberschrift ansagen.

<table>
  <caption>Öffnungszeiten der Beratungsstelle</caption>
  <thead>
    <tr><th scope="col">Tag</th><th scope="col">Uhrzeit</th></tr>
  </thead>
  <tbody>
    <tr><th scope="row">Montag</th><td>9–16 Uhr</td></tr>
    <tr><th scope="row">Dienstag</th><td>9–13 Uhr</td></tr>
  </tbody>
</table>

Stolperstein: Tabellen für Layout sind seit Jahren tabu, tauchen aber in E-Mail-Templates und alten CMS-Bausteinen weiter auf. Für Layout gibt es Grid und Flexbox.

Bewegung reduzieren

Animationen können Schwindel und Übelkeit auslösen. Wer die Systemeinstellung respektiert, erfüllt WCAG 2.3.3 mit drei Zeilen.

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

Stolperstein: Ganz auf 0 zu setzen bringt Skripte durcheinander, die auf das Ende einer Animation warten – daher der Wert von 0,01 Millisekunden statt null.

Wann ein Snippet nicht reicht

Drei Muster habe ich hier bewusst nicht abgekürzt, weil eine Kopiervorlage sie nicht trägt: Tabs, Comboboxen und Karussells. Sie brauchen Zustandsverwaltung, Tastaturmuster mit Pfeiltasten und eine Entscheidung darüber, was beim Wechsel angesagt wird – das lässt sich nicht in zehn Zeilen unterbringen, ohne etwas Falsches zu behaupten.

Wenn du eines dieser Muster brauchst, ist der Weg über den jeweiligen Artikel kürzer als über ein Snippet, das du danach reparieren musst. Und ganz allgemein: Bevor ich ein ARIA-Muster nachbaue, schau ich immer erst, ob HTML es schon kann. In den letzten Projekten war die Antwort öfter „ja“, als ich beim Anfangen gedacht hätt.

Häufige Fehler beim Kopieren

  • aria-label an einem <div>. Ohne Rolle wird der Name meist ignoriert. Namen brauchen ein Element, das eine Rolle hat.
  • role="button" an einem <div>, ohne tabindex="0" und ohne Tastatur-Handler. Dann nimm einfach <button>.
  • Doppelte IDs aus mehrfach eingefügten Snippets – zerstört jede for- und aria-describedby-Verknüpfung.
  • aria-hidden="true" an einem fokussierbaren Element. Es verschwindet für Screenreader, bleibt aber per Tab erreichbar – ein Widerspruch, den Prüfwerkzeuge zuverlässig melden.
  • Placeholder statt Label. Verschwindet beim Tippen und hat oft zu wenig Kontrast.

Häufige Fragen

Darf ich diese Snippets in kommerziellen Projekten verwenden?

Ja. Es sind Standardmuster aus HTML, CSS und minimalem ARIA – daran gibt es nichts zu lizenzieren. Was du mitnehmen solltest, ist nicht der Code, sondern die Begründung dahinter.

Warum steht hier so wenig ARIA?

Weil ARIA nichts hinzufügt, was HTML nicht schon kann, sondern nur Informationen für assistive Technologien ergänzt. Falsch gesetzt macht es Elemente unbenutzbar. Ein <button> ist zuverlässiger als jedes role="button".

Ersetzt eine Komponentenbibliothek diese Snippets?

Teilweise. Gute Bibliotheken bringen getestete Muster mit – aber sie treffen Entscheidungen, die du kennen solltest, etwa welchen Namen ein Icon-Button bekommt oder ob ein Dialog modal ist. Die Snippets hier sind der Maßstab, an dem man eine Bibliothek prüft.

Wie teste ich, ob ein kopiertes Snippet funktioniert?

Mit drei Durchläufen: einmal nur mit der Tastatur, einmal mit 200 % Zoom, einmal mit einem Screenreader über den betroffenen Bereich. Das dauert wenige Minuten und findet mehr als jedes automatische Werkzeug – siehe Selbst testen.

Vom Snippet zur Komponente

Jedes Snippet gehört zu einem ausführlichen Artikel – und dort warten auch die Muster, die für eine Kopiervorlage zu groß sind:

Snippet / Thema Der passende Artikel
Skip-Link Skip-Links
Icon-Button Icons & SVGs
<details>-Akkordeon Akkordeons
<dialog> Dialoge & Modals
Feld + Fehlermeldung Fehlermeldungen
Fehlerliste, Pflichtfelder Validierung & Pflichtfelder
Breadcrumbs Breadcrumbs
Live-Region Status & Benachrichtigungen
Datentabelle Komplexe Datentabellen
Datumseingabe Datepicker
Tabs, Comboboxen, Karussells Tabs · Comboboxen · Slider & Karussells

Für die schweren Muster gibt es außerdem ein eigenes Werkzeug: Diese Bibliothek ist fertig zum Kopieren, der Komponenten-Baukasten ist konfigurierbar. Er stellt die Varianten nebeneinander, die hier absichtlich fehlen – natives <dialog> gegen ARIA-Nachbau, <details> gegen Button mit aria-expanded, Tabs mit automatischer gegen manuelle Aktivierung – jeweils mit Vorschau, Code und einem Testprotokoll für Tastaturweg und Screenreader-Ausgabe. Kurz: Bibliothek, wenn die Frage „wie schreibt man das?“ lautet. Baukasten, wenn sie „welche Variante nehme ich?“ lautet.

Fazit

Zwölf Muster, die den größten Teil des Alltags abdecken – und in neun Fällen ohne JavaScript auskommen. Wer lieber zuerst das Warum versteht, folgt den Links in die barrierefreien Komponenten; welches WCAG-Kriterium hinter einem Muster steht, verrät die Kriterien-Referenz. Zum schnellen Nachschlagen passen außerdem die Cheat-Sheets & Checklisten, das Glossar und die kommentierte Tool-Sammlung.

Quellen

Gratis E-Book PDF Das Praxishandbuch

Kostenloses E-Book

Das Praxishandbuch für sauberes, zugängliches Web

Alles rund um semantisches HTML, Barrierefreiheit, WCAG & BFSG, GEO und SEO — praxisnah und am echten Code. In mehreren Feedbackschleifen von Leserinnen und Lesern verbessert.

  • 3.000+ Downloads
  • 7. Auflage
  • 37 Seiten
  • PDF

Kein Spam. Abmeldung jederzeit mit einem Klick möglich.