Barrierefreiheit
Seitenstruktur: was ein Screenreader von deiner Website übrig lässt
Eine Website hat zwei Fassungen.
9 Min. Lesezeit
Von Timo Wessels Veröffentlicht am
Eine Website hat zwei Fassungen. Die eine siehst du: Farben, Bilder, Spalten, Abstände. Die andere ist die, die an Screenreader, Suchmaschinen und KI-Systeme geht — und die besteht ausschließlich aus Struktur.
Wenn diese zweite Fassung nur aus einer Aneinanderreihung bedeutungsloser Kästen besteht, hilft die erste Fassung niemandem. Sie ist dann gar nicht vorhanden.
Was tatsächlich beim Screenreader ankommt
Der Browser baut aus deinem HTML zwei Dinge parallel auf.
Das erste ist das DOM — die vollständige Struktur aller Elemente, aus der die sichtbare Seite gerendert wird.
Das zweite ist der Accessibility Tree, ein abgespecktes Abbild davon. Er enthält nur, was Hilfsmittel brauchen: Rollen, Namen, Zustände und Eigenschaften.
Was hineinkommt:
- Ein
<h1>wird zu: Rolle „Überschrift", Ebene 1. - Ein
<p>wird zu: Text. - Ein
<img>wird zu einem Element mit dem Namen aus demalt-Attribut. - Ein
<button>wird zu: Rolle „Schaltfläche", benutzbar, mit dem Zustand aktiv oder deaktiviert.
Was nicht hineinkommt:
- Ein
<div>oder<span>ohne weitere Angaben. Es bekommt die Rolle „generic" — also: kein Inhalt, keine Bedeutung. - Alles, was per CSS mit
display: noneversteckt ist.
Der letzte Punkt hat eine Folge, die viele überrascht: CSS beeinflusst, was im Accessibility Tree landet. Was du optisch ausblendest, verschwindet auch für den Screenreader. Das ist meistens richtig — es ist aber der Grund, warum eine per CSS ausgeblendete Navigation für Tastaturnutzer manchmal trotzdem noch durchtabbt wird, wenn sie mit anderen Mitteln versteckt wurde.
Die praktische Konsequenz: Native HTML-Elemente erzeugen Rollen und Zustände von selbst. Ein <button type="button">Angebot anfordern</button> ist für einen Screenreader ohne jede Zusatzarbeit als Schaltfläche erkennbar und bedienbar. Ein <div> mit einem Klick-Ereignis, das genauso aussieht, ist es nicht — man kann es nicht mit der Tastatur erreichen, es wird nicht als Schaltfläche angesagt, und es reagiert nicht auf Enter.
Das ist der Kern des Themas: Verwende das richtige Element, dann hast du achtzig Prozent der Arbeit nicht.
(Rheinwerk, Barrierefreie Webseiten, Kap. 3.7)
Semantisches HTML
Semantik bedeutet, ein Element danach zu wählen, was der Inhalt ist — nicht danach, wie er aussehen soll.
Jedes HTML-Element trägt eine Bedeutung. Mit genau zwei Ausnahmen: <div> und <span> bedeuten nichts. Sie sind reine Behälter.
Der Unterschied in der Praxis:
<!-- ohne Bedeutung -->
<div class="ueberschrift">Leistungen</div>
<div class="text">Wir bieten drei Leistungen an:</div>
<div class="liste">
<div>Barrierefreiheitsprüfung</div>
<div>Ladezeitanalyse</div>
<div>Wartung</div>
</div>
<!-- mit Bedeutung -->
<h2>Leistungen</h2>
<p>Wir bieten drei Leistungen an:</p>
<ul>
<li>Barrierefreiheitsprüfung</li>
<li>Ladezeitanalyse</li>
<li>Wartung</li>
</ul>
Beides kann optisch identisch aussehen. Aber in der zweiten Fassung sagt der Screenreader an: „Überschrift Ebene 2, Leistungen" und „Liste mit drei Einträgen". Der Nutzer weiß, was ihn erwartet, und kann direkt zur Liste springen. In der ersten Fassung hört er drei Wörter ohne Zusammenhang.
Dasselbe gilt für Suchmaschinen und für KI-Systeme, die deine Seite auswerten: Sie lesen die Struktur, nicht das Aussehen.
Das dahinterstehende Kriterium ist 1.3.1 „Info und Beziehungen", Stufe A: Struktur und Beziehungen, die optisch erkennbar sind, müssen auch im Code vorhanden sein.
(Rheinwerk, Barrierefreie Webseiten, Kap. 3.2)
Die Bereiche einer Seite
HTML kennt Elemente, die ganze Seitenbereiche kennzeichnen. Sie heißen im Fachjargon Landmarks — Orientierungspunkte. Ein Screenreader kann eine Liste dieser Bereiche ausgeben und direkt dorthin springen.
| Element | Was es kennzeichnet |
|---|---|
<header> |
Kopfbereich mit Logo, Titel, oft der Navigation |
<nav> |
Navigationsbereich |
<main> |
Der Hauptinhalt der Seite — genau einmal pro Seite |
<article> |
In sich abgeschlossener Inhalt, der für sich stehen könnte |
<section> |
Ein thematisch zusammengehöriger Abschnitt |
<aside> |
Nebeninhalt, Seitenleiste, Zusatzinformation |
<footer> |
Fußbereich mit Kontakt, rechtlichen Links, Urheberrecht |
Ein vollständiges Grundgerüst sieht so aus:
<body>
<a href="#inhalt" class="sprunglink">Zum Inhalt</a>
<header>
<a href="/"><img src="logo.svg" alt="Startseite Musterbetrieb"></a>
<nav aria-label="Hauptnavigation">
<ul>
<li><a href="/leistungen">Leistungen</a></li>
<li><a href="/kontakt">Kontakt</a></li>
</ul>
</nav>
</header>
<main id="inhalt">
<h1>Leistungen</h1>
<p>…</p>
</main>
<footer>
<p>Musterbetrieb GmbH · <a href="/impressum">Impressum</a></p>
</footer>
</body>
Ein Detail, das oft fehlt: Wenn eine Seite mehrere <nav>-Bereiche hat — Hauptnavigation, Fußzeilennavigation, Brotkrumenpfad — braucht jeder eine eigene Bezeichnung über aria-label. Sonst hört der Nutzer dreimal „Navigation" und weiß nicht, welche welche ist.
<main> gibt es genau einmal pro Seite. Es ist der Bereich, zu dem der Screenreader-Nutzer direkt springt, wenn er den Kopfbereich überspringen will.
(Rheinwerk, Barrierefreie Webseiten, Kap. 3.4 und 8.1)
Der Sprunglink
Erfolgskriterium 2.4.1 „Blöcke umgehen", Stufe A: Es muss einen Weg geben, wiederkehrende Bereiche zu überspringen.
Der Gedanke dahinter: Auf jeder Unterseite stehen dieselben zwanzig Menüpunkte. Wer sich linear durch die Seite bewegt — mit Tastatur oder Screenreader — müsste sie auf jeder Seite erneut durchgehen, bevor der eigentliche Inhalt beginnt.
Die übliche Lösung ist ein Sprunglink als allererstes Element im <body>:
<a href="#inhalt" class="sprunglink">Zum Inhalt</a>
Er ist normalerweise unsichtbar und wird sichtbar, sobald er den Fokus bekommt:
.sprunglink {
position: absolute;
inset-block-start: -100%;
}
.sprunglink:focus {
position: static;
/* oder: inset-block-start: 0; */
}
Wichtig dabei: Er darf nicht mit display: none versteckt werden. Dann ist er auch für die Tastatur weg und erfüllt seinen Zweck nicht.
Zwei Dinge, die ich in der Praxis regelmäßig sehe:
- Der Sprunglink ist da, aber er wird beim Fokussieren nicht sichtbar. Dann springt der Fokus für einen Sehenden scheinbar ins Nichts.
- Der Sprunglink zeigt auf eine
id, die es nicht gibt. Dann passiert schlicht nichts.
Ein korrekt gesetztes <main> mit einer id und ein sichtbar werdender Sprunglink darauf — das ist die ganze Lösung.
Die Reihenfolge im Quelltext
Erfolgskriterium 1.3.2 „Bedeutungsvolle Reihenfolge", Stufe A: Die Reihenfolge im Code muss der Reihenfolge entsprechen, in der der Inhalt gelesen werden soll.
Screenreader lesen linear, von oben nach unten. Was im Quelltext an vierter Stelle steht, kommt an vierter Stelle.
Der Konflikt entsteht durch modernes CSS. Rasterlayouts können Elemente frei anordnen — ein Element, das im Code zuerst steht, kann optisch unten rechts landen. Für Sehende stimmt die Anordnung dann, für alle anderen nicht.
Ein konkretes Beispiel: Ein Produktbild steht optisch über der Überschrift. Im Code muss es trotzdem nach der Überschrift stehen, weil die Überschrift ansagt, worum es geht. Sonst hört der Nutzer erst den Alternativtext eines Bildes und dann, wovon das Bild eigentlich war.
Die Regel für die Praxis: Schreib den Quelltext in der Reihenfolge, in der du den Inhalt vorlesen würdest. Ordne dann per CSS an. Nicht umgekehrt.
Das betrifft auch den Wechsel zwischen Desktop und Smartphone: Wenn Spalten auf dem Telefon in einer anderen Reihenfolge erscheinen als auf dem Desktop, ist mindestens eine der beiden Reihenfolgen falsch.
(Rheinwerk, Barrierefreie Webseiten, Kap. 3.5)
Zwei Kleinigkeiten mit großer Wirkung
Die Sprachangabe. Ganz oben im Dokument:
<html lang="de">
Ohne diese Angabe rät der Screenreader die Sprache — und liest deutschen Text im Zweifel mit englischer Aussprache vor. Das Ergebnis ist unverständlich. Ein einziges Attribut, und es ist erledigt.
Für einzelne fremdsprachige Passagen im Text gilt dasselbe im Kleinen:
<p>Das Verfahren heißt <span lang="en">progressive enhancement</span>.</p>
Der Seitentitel. Jede Seite braucht einen eigenen, aussagekräftigen <title>. Er ist das Erste, was ein Screenreader beim Laden ansagt, und die einzige Orientierung, wenn jemand zwischen mehreren Tabs wechselt. Fünf Unterseiten mit dem Titel „Startseite" sind ein echter Fund.
Wie du das selbst prüfst
Die Struktur ansehen. Die Browser-Erweiterung HeadingsMap zeigt Überschriftenstruktur und Landmarks als Gliederung an. Die Erweiterung Web Developer kann Überschriften und Bereiche direkt auf der Seite markieren. Beides kostenlos, beides in einer Minute installiert.
Die Entwicklerwerkzeuge. In Chrome und Edge gibt es unter „Elements" einen Reiter „Accessibility", der den Accessibility Tree für das ausgewählte Element anzeigt — mit Rolle, Name und Zuständen. Das ist die genaueste Antwort auf die Frage: Was kommt hier eigentlich an?
Die Landmark-Liste im Screenreader. In NVDA lässt sich eine Liste der Bereiche aufrufen. Wenn dort nur „Hauptbereich" und sonst nichts steht, fehlen die Landmarks.
Der Tab-Test auf den Sprunglink. Seite laden, einmal Tab drücken. Erscheint ein Sprunglink? Führt er zum Inhalt?
Der Quelltext-Blick. Rechtsklick, Seitenquelltext anzeigen. Such nach <main, <nav, <header, <footer. Wenn keins davon vorkommt und stattdessen überall <div class="…"> steht, hast du das Ergebnis.
Was zu tun ist
Prüf zuerst, was dein Theme mitbringt. Die meisten dieser Elemente kommen aus dem Theme, nicht aus deinen Inhalten. Ein sauber gebautes Theme setzt <header>, <nav>, <main> und <footer> von selbst und bringt einen funktionierenden Sprunglink mit. Ein schlecht gebautes setzt überall <div>. Der Unterschied ist bei der Themewahl wichtiger als jedes Gestaltungsmerkmal — und er ist der Grund, warum ich bei einem Umbau lieber das Fundament tausche, als hundert Einzelstellen zu reparieren.
Setz lang="de", falls es fehlt. Das ist der billigste Fund überhaupt.
Gib jedem <nav> eine Bezeichnung.
Sorg dafür, dass genau ein <main> existiert und der Sprunglink darauf zeigt.
Und beim Bauen von Inhalten: Benutze im Editor die vorgesehenen Formate — Überschrift, Liste, Zitat — statt Text optisch nachzubauen. Eine Liste, die aus Absätzen mit vorangestelltem Bindestrich besteht, sieht aus wie eine Liste und ist keine. Der Aufwand ist derselbe, das Ergebnis nicht.
Quellen
- Rheinwerk, Barrierefreie Webseiten, Kap. 3.2 (Semantisches HTML) — Semantik als Beschreibung dessen, was der Inhalt ist,
<div>und<span>als einzige bedeutungslose Elemente, das Gegenüberstellungsbeispiel mit Überschrift und Liste, die HTML5-Bereichselemente, und die Warnung davor, Überschriftenebenen wegen ihrer Größe zu wählen. - Rheinwerk, Barrierefreie Webseiten, Kap. 3.4 (Semantisches HTML für Barrierefreiheit) — die lineare Ausgabe von Screenreadern, die Aufteilung der Strukturelemente in Navigation und Inhaltsstruktur,
<main>als Voraussetzung für WCAG 2.4.1, der Nutzen semantischer Auszeichnung für Suchmaschinen, und HeadingsMap als Prüfwerkzeug. - Rheinwerk, Barrierefreie Webseiten, Kap. 3.5 (Bedeutungsvolle Reihenfolge) — WCAG 1.3.2 und das Beispiel, dass ein Produktbild im Code nach seiner Überschrift stehen muss, auch wenn es optisch darüber erscheint.
- Rheinwerk, Barrierefreie Webseiten, Kap. 3.7 (Accessibility Tree) — der Accessibility Tree als Abstraktion des DOM mit Rollen, Namen, Zuständen und Eigenschaften, die Zuordnung von
<h1>,<p>,<img>und<div>, die Rolle „generic", der Ausschluss von per CSS versteckten Inhalten und die daraus folgende Wirkung von CSS auf die Semantik, die Accessibility-API-Implementierungen UI Automation und NSAccessibility, die Zuordnungsspezifikation HTML-AAM, und die automatische Erzeugung von Rollen durch native HTML-Elemente am Beispiel eines Buttons. - Rheinwerk, Barrierefreie Webseiten, Kap. 8.1 (Navigation) — WCAG 2.4.1 „Blöcke umgehen", der Sprunglink mit Codebeispiel und der Hinweis, ihn per CSS bei Fokus sichtbar zu machen, sowie die Aufzählung der Bereichselemente mit ihrer jeweiligen Funktion für Screenreader-Nutzer.
- Atlas,
accessibility/criteria/1-3-1-info-and-relationships.mdund2-4-1-bypass-blocks.md— Einordnung der Kriterien nach Prinzip, Richtlinie und Konformitätsstufe. - Eigene Prüfpraxis — die zwei häufigsten Sprunglink-Fehler (nicht sichtbar bei Fokus, Ziel-
idfehlt), die Bezeichnung mehrerer<nav>-Bereiche überaria-label, der Quelltext-Schnelltest auf Bereichselemente, die Einordnung der Themequalität als wichtigster Hebel, und der Hinweis auf per Bindestrich nachgebaute Listen im Editor.