Fokus-Management in Single-Page-Apps barrierefrei
Single-Page-Apps fühlen sich schnell und modern an: Ein Klick auf einen Link tauscht den Inhalt aus, ohne dass die Seite komplett neu lädt. Genau dieser Komfort wird für Tastatur- und Screenreader-Nutzer aber häufig zur Barriere. Bei einem klassischen Seitenwechsel setzt der Browser den Fokus zurück und der Screenreader liest den neuen Seitentitel vor. In einer SPA passiert das nicht von allein: Der Fokus bleibt am angeklickten Link hängen, der Seitentitel bleibt unverändert, und der Wechsel der Ansicht wird nicht angekündigt. Wie verbreitet Bedienprobleme insgesamt sind, zeigt der WebAIM Million Report: 95,9% (WebAIM Million, 2024) aller untersuchten Startseiten hatten erkennbare WCAG-Verstöße, im Schnitt 56,8 (WebAIM Million, 2024) pro Seite. Dieser Leitfaden zeigt, wie Sie Routenwechsel in JavaScript-Frameworks barrierefrei gestalten - mit korrektem Fokus-Management, gepflegtem Seitentitel und Ankündigung per Live-Region - als belastbare Grundlage für Ihre barrierefreie Webentwicklung.
Das Wichtigste in Kürze
- Beim Routenwechsel übernimmt der Browser kein Fokus-Management - die App muss den Fokus aktiv auf die neue Ansicht lenken.
- In der Regel wandert der Fokus auf die Hauptüberschrift (H1) der neuen Route, die dafür mit tabindex=-1 fokussierbar gemacht wird.
- Der Seitentitel (document.title) muss sich bei jedem View-Wechsel ändern, damit Screenreader und Lesezeichen die richtige Ansicht abbilden (WCAG 2.4.2).
- Eine höflich aktualisierte Live-Region (aria-live=polite) kann den Wechsel zusätzlich ankündigen, wenn der Fokus nicht ausreicht (WCAG 4.1.3).
- React, Vue, Angular und Svelte liefern kein eingebautes Fokus-Management - es ist stets Aufgabe der Anwendung, es bewusst zu ergänzen.
Warum Routenwechsel in SPAs zur Barriere werden
Bei einer klassischen Website führt jeder Link zu einem neuen Dokument. Der Browser lädt die Seite, setzt den Fokus an den Dokumentanfang und der Screenreader liest den neuen Seitentitel vor - all das ohne Zutun der Entwickler. In einer Single-Page-App passiert beim Klick auf einen internen Link technisch etwas völlig anderes: Der Router fängt die Navigation ab, tauscht einen Teil des DOM aus und aktualisiert die URL über die History-API. Es gibt keinen echten Seitenwechsel, also setzt der Browser auch den Fokus nicht zurück. Der Fokus verbleibt auf dem angeklickten Link, der nach dem View-Wechsel häufig gar nicht mehr existiert (W3C/WAI).
Für sehende Maus-Nutzer ist das unsichtbar. Für Tastatur- und Screenreader-Nutzer ist es ein echtes Problem: Der Screenreader bleibt stumm, weil er Änderungen am Seitentitel nicht aktiv überwacht, und der nächste Tab-Schritt führt an eine unvorhersehbare Stelle. Diese Situation betrifft viele Menschen unmittelbar: Ende 2023 lebten in Deutschland rund 7,9 Mio. (Statistisches Bundesamt, 2024) schwerbehinderte Menschen, davon hatten rund 4% (Statistisches Bundesamt, 2024) eine Blindheit oder Sehbeeinträchtigung. Weil SPA-Frameworks heute den Markt prägen - 40,6% (Stack Overflow Developer Survey, 2024) der Entwickler setzen React ein, weitere nutzen Vue oder Angular - betrifft das Thema einen sehr grossen Teil moderner Web-Anwendungen. Hinzu kommt, dass viele Nutzer Tastatur und Screenreader nicht aus einer dauerhaften Beeinträchtigung heraus verwenden, sondern situativ - etwa bei einer vorübergehenden Verletzung oder in einer Umgebung, in der die Maus unpraktisch ist. Ein robustes Fokus-Management hilft daher einer deutlich grösseren Gruppe als nur den Menschen mit dauerhafter Behinderung.
Der Browser springt nicht automatisch ein
Die drei WCAG-Bausteine eines barrierefreien Routenwechsels
Ein zugänglicher Routenwechsel entsteht aus dem Zusammenspiel von drei Maßnahmen. Keine davon ersetzt die anderen vollständig - gemeinsam sorgen sie dafür, dass alle Nutzergruppen mitbekommen, dass sich die Ansicht geändert hat. Die folgende Übersicht fasst zusammen, welche WCAG-Erfolgskriterien hier zusammenspielen (W3C/WAI). Diese Punkte prüfen wir im Rahmen unserer Leistungen systematisch ab.
Fokus setzen
Nach dem View-Wechsel wandert der Fokus auf die Hauptüberschrift oder den Hauptinhalt der neuen Route, der dafür mit tabindex=-1 fokussierbar gemacht wird (WCAG 2.4.3).
Seitentitel pflegen
document.title ändert sich bei jedem Routenwechsel und beschreibt die aktuelle Ansicht, damit Lesezeichen und Screenreader die richtige Seite abbilden (WCAG 2.4.2).
Wechsel ankündigen
Eine höflich aktualisierte Live-Region (aria-live=polite) teilt den Wechsel mit, wenn der Fokuswechsel allein nicht klar genug ist (WCAG 4.1.3).
In der Praxis bildet das Fokus-Management die Grundlage, der Seitentitel sorgt für Orientierung und die Live-Region ist die ergänzende Sicherung. Welcher Mix sinnvoll ist, hängt vom Framework und der Komplexität der Ansicht ab. Diese Bausteine bauen direkt auf den Grundlagen der Tastaturnavigation in der Webentwicklung auf und ergänzen die saubere Verwendung von ARIA-Rollen, Zuständen und Live-Regions.
Der Lebenszyklus eines barrierefreien Routenwechsels
- 1
Link wird aktiviert
Per Klick oder Tastatur wird ein interner Link ausgelöst; der Router fängt die Navigation ab und verhindert den vollständigen Reload.
- 2
Router rendert die neue View
Der neue Inhalt wird in das DOM eingesetzt, die URL über die History-API aktualisiert und der Seitentitel passend gesetzt.
- 3
Fokus wird gesetzt
Der Fokus wandert programmatisch auf die neue Hauptüberschrift oder den Hauptinhalt, der mit tabindex=-1 fokussierbar gemacht wurde.
- 4
Wechsel wird angekündigt
Eine Live-Region meldet den Wechsel höflich, falls der Fokuswechsel allein nicht ausreichend kommuniziert wird.
Fokus setzen: auf die Überschrift der neuen Route
Das verlässlichste Verfahren ist, den Fokus nach dem Routenwechsel auf die Hauptüberschrift (H1) der neuen Ansicht zu setzen. Überschriften sind von Haus aus nicht fokussierbar, deshalb erhalten sie tabindex=-1, womit sie per JavaScript fokussiert werden können, ohne in die natürliche Tab-Reihenfolge zu geraten. Beim Fokussieren liest der Screenreader die Überschrift vor - der Nutzer erfährt sofort, wo er gelandet ist, und der nächste Tab-Schritt beginnt sinnvoll im neuen Inhalt. Alternativ kann der Fokus auf einen Container mit der Rolle main oder einen dedizierten Anker am Seitenanfang gesetzt werden (W3C/WAI).
Wichtig ist die zeitliche Reihenfolge: Der Fokus darf erst gesetzt werden, wenn der neue Inhalt im DOM steht und sichtbar ist. In Frameworks bedeutet das, den Fokus nach dem Render-Zyklus zu setzen - etwa in einem Effekt-Hook oder Lifecycle-Callback, der nach dem Einfügen des neuen Inhalts läuft. Ein sichtbarer Fokus-Indikator ist dabei Pflicht, damit sehende Tastaturnutzer die neue Position erkennen. Die Details dazu vertieft unser Beitrag zur Tastaturnavigation in der Webentwicklung.
// Nach jedem Routenwechsel den Fokus auf die
// neue Hauptüberschrift lenken.
function onRouteChanged() {
const heading = document.querySelector('main h1');
if (heading) {
// Überschrift programmatisch fokussierbar machen,
// ohne sie in die Tab-Reihenfolge aufzunehmen.
heading.setAttribute('tabindex', '-1');
heading.focus();
}
}import { useEffect, useRef } from 'react';
import { useLocation } from 'react-router-dom';
export function RouteView({ title, children }) {
const headingRef = useRef(null);
const location = useLocation();
useEffect(() => {
document.title = title; // Seitentitel pflegen
headingRef.current?.focus(); // Fokus auf neue View
}, [location.pathname, title]);
return (
<main>
<h1 tabIndex={-1} ref={headingRef}>{title}</h1>
{children}
</main>
);
}Häufiger Fehler: Fokus zu früh oder gar nicht gesetzt
Seitentitel pflegen und den Wechsel ankündigen
Jede Route braucht einen eigenen, aussagekräftigen Seitentitel. WCAG 2.4.2 Seite mit Titel versehen verlangt, dass jede Ansicht einen beschreibenden Titel hat, der ihren Zweck nennt (W3C/WAI). In einer SPA muss document.title bei jedem Routenwechsel aktiv gesetzt werden, weil der Browser ihn nicht mehr aus einem neuen Dokument übernimmt. Ein gepflegter Titel hilft nicht nur Screenreader-Nutzern, sondern auch beim Setzen von Lesezeichen, beim Wechsel zwischen Browser-Tabs und im Verlauf. Screenreader lesen den Titel allerdings nur beim echten Laden einer Seite vor und überwachen Titel-Änderungen nicht aktiv - deshalb ersetzt der Titel das Fokus-Management nicht, sondern ergänzt es.
Wenn der Fokuswechsel allein nicht ausreicht - etwa bei Teil-Updates innerhalb derselben Route - hilft eine Live-Region. Ein leeres Element mit aria-live=polite, das beim Wechsel mit einem kurzen Text wie Produkte geladen befüllt wird, kündigt die neue Ansicht höflich an, ohne den Nutzer zu unterbrechen. WCAG 4.1.3 Statusmeldungen beschreibt genau diesen Mechanismus: Statusänderungen sollen ohne Fokuswechsel wahrnehmbar gemacht werden (W3C/WAI). Wie Live-Regions korrekt aufgebaut werden, ohne Doppel-Ankündigungen zu erzeugen, vertieft unser Beitrag zu ARIA-Rollen, Zuständen und Live-Regions.
<!-- Globale, visuell versteckte Live-Region.
Einmal im App-Layout, ausserhalb des Router-Outlets. -->
<div id="route-announcer"
aria-live="polite"
aria-atomic="true"
class="visually-hidden"></div>// Beim Routenwechsel die neue Ansicht ankündigen.
function announceRoute(title) {
const region = document.getElementById('route-announcer');
if (!region) return;
// Kurz leeren, damit gleiche Texte erneut
// vorgelesen werden.
region.textContent = '';
window.requestAnimationFrame(() => {
region.textContent = title + ' geladen';
});
}| Aspekt | Häufiger Fehler | Barrierefrei umgesetzt |
|---|---|---|
| Fokus nach Wechsel | Fokus bleibt am alten Link | Fokus wandert auf die neue Überschrift |
| Seitentitel | Titel bleibt unverändert | document.title spiegelt die Route wider |
| Ankündigung | Kein Hinweis auf den Wechsel | Live-Region meldet die neue Ansicht |
| Tab-Reihenfolge | Nächster Tab springt unvorhersehbar | Nächster Tab beginnt im neuen Inhalt |
| Fokus-Indikator | Kein sichtbarer Fokus | Deutlich sichtbarer Fokus-Ring |
| Zeitpunkt | Fokus vor dem Render gesetzt | Fokus nach dem Render-Zyklus gesetzt |
Framework-Unterschiede: React, Vue, Angular und Svelte
Keines der verbreiteten JavaScript-Frameworks bringt ein eingebautes Fokus-Management für Routenwechsel mit - es bleibt stets Aufgabe der Anwendung. Die Frameworks unterscheiden sich aber darin, wo der passende Zeitpunkt für das Setzen des Fokus liegt. In React eignet sich ein useEffect-Hook, der auf den Pfadwechsel reagiert; bei Vue der Router-Hook afterEach in Kombination mit nextTick; bei Angular das NavigationEnd-Ereignis des Routers; und bei Svelte ein after-navigate-Callback. Allen gemeinsam ist, dass der Fokus erst gesetzt werden darf, wenn die neue View im DOM steht.
Wichtig ist auch, dass ein einmal gebautes Muster konsequent über die gesamte Anwendung gilt. In der Begleitung von 50+ (Projekterfahrung) Projekten sehen wir häufig, dass Fokus-Management nur für einzelne Routen umgesetzt wurde - der Rest der Anwendung bleibt dann unzugänglich. Eine zentrale Komponente, die für jede Route Titel, Fokus und Ankündigung übernimmt, reduziert diese Lücken deutlich. Dieselbe Sorgfalt gilt für dynamisch nachgeladene Inhalte, wie der Beitrag zu barrierefreien Fehlermeldungen und Statusmeldungen zeigt. Hilfreich ist es, das Verhalten in der internen Komponentenbibliothek zu dokumentieren und in automatisierten Tests abzusichern, damit das Fokus-Management bei künftigen Umbauten nicht versehentlich verloren geht.
React
Ein useEffect-Hook reagiert auf den Pfadwechsel, setzt document.title und fokussiert die neue Überschrift nach dem Render.
Vue
Der Router-Hook afterEach setzt den Titel; nextTick stellt sicher, dass der Fokus erst nach dem DOM-Update gesetzt wird.
Angular
Das NavigationEnd-Ereignis des Routers eignet sich, um den Titel zu setzen und den Fokus auf den neuen Hauptinhalt zu lenken.
Svelte
Ein after-navigate-Callback bietet den passenden Zeitpunkt, um Titel, Fokus und Live-Region-Ankündigung zu aktualisieren.
Eine zentrale Route-View-Komponente als robuste Grundlage
Sonderfälle: Teil-Updates, Modals und unendliches Scrollen
Nicht jede Änderung in einer SPA ist ein vollständiger Routenwechsel. Ein Filter, der nur die Ergebnisliste austauscht, sollte den Fokus nicht erzwingen, sondern das Ergebnis über eine Live-Region melden - sonst verliert der Nutzer seine Position. Wird beim Routenwechsel ein modaler Dialog geöffnet, gelten dessen eigene Regeln: Fokus-Falle, inerter Hintergrund und Fokusrückgabe, wie sie der Beitrag zu barrierefreien Modals und Overlays beschreibt. Beim unendlichen Scrollen wiederum sollte der Fokus beim Nachladen nicht verspringen, und neue Inhalte sollten so eingefügt werden, dass die Tab-Reihenfolge erhalten bleibt.
Auch das Verhalten beim Zurücknavigieren verdient Aufmerksamkeit. Wenn ein Nutzer über den Zurück-Button des Browsers eine frühere Route aufruft, sollte die App idealerweise die vorherige Scroll- und Fokusposition wiederherstellen. Das ist anspruchsvoll, aber gerade für Tastaturnutzer ein deutlicher Gewinn. Bewegungen beim View-Wechsel sollten prefers-reduced-motion respektieren, damit Animationen niemanden überfordern.
- Beim Routenwechsel Fokus auf die neue Hauptüberschrift (H1, tabindex=-1) gesetzt
- Fokus erst nach dem Render-Zyklus gesetzt, auf ein vorhandenes sichtbares Element
- document.title bei jedem Routenwechsel aktualisiert (WCAG 2.4.2)
- Globale Live-Region (aria-live=polite) kündigt den Wechsel an (WCAG 4.1.3)
- Sichtbarer Fokus-Indikator auf dem fokussierten Ziel vorhanden
- Teil-Updates melden Ergebnisse, ohne den Fokus zu erzwingen
- Zurück-Navigation stellt Scroll- und Fokusposition möglichst wieder her
- Mit Tastatur und Screenreader über alle Routen gegengeprüft
Eine Single-Page-App ist erst dann barrierefrei navigierbar, wenn jeder Routenwechsel den Fokus mitnimmt. Wer nur den Inhalt austauscht, aber den Fokus vergisst, lässt Tastatur- und Screenreader-Nutzer im Ungewissen.
Routenwechsel berühren gleich mehrere WCAG-Erfolgskriterien auf einmal: 2.4.2 Seite mit Titel versehen, 2.4.3 Fokus-Reihenfolge und 4.1.3 Statusmeldungen (W3C/WAI). Deshalb ist ein sauber umgesetztes Fokus-Management oft ein Hebel, der mehrere Befunde in einem WCAG-Audit gleichzeitig adressiert. Wenn Sie das Muster von Anfang an in einer zentralen Komponente verankern, vermeiden Sie eine ganze Klasse wiederkehrender Fehler - und schaffen eine verlässliche Grundlage für Ihre barrierefreie Webentwicklung.