fieldset pro Schritt, aria-current im Stepper und verlustfreie Zurück-Navigation im Wizard-Pattern
Ein mehrstufiges Formular ist mehr als eine Aneinanderreihung einzelner Formularseiten: Es braucht eine erkennbare Gruppierung pro Schritt, eine Fortschrittsanzeige, die den aktuellen Schritt eindeutig kommuniziert, eine aktive Ankündigung jedes Schrittwechsels für Screenreader-Nutzer und eine Zurück-Navigation, die eingegebene Daten zuverlässig erhält. Dieses allgemeine Wizard-Pattern gilt für Registrierungsassistenten, mehrstufige Konfiguratoren und Umfragen genauso wie für jeden anderen mehrstufigen Formularprozess abseits des Checkouts.
Inhaltsverzeichnis
- 1. Das Wizard-Pattern als eigenständiges, allgemeines Problem
- 2. fieldset und legend: Gruppierung der Formularfelder pro Schritt
- 3. Progress-Stepper Markup: aria-current für den aktuellen Schritt
- 4. Screenreader-Ankündigung von Schrittwechseln
- 5. Fokus-Management beim Schrittwechsel: Fokus auf die Schritt-Überschrift setzen
- 6. Validierung pro Schritt vor dem Weiterschalten und Fehlerzusammenfassung
- 7. Zwischenspeichern und Zurück-Navigation ohne Datenverlust
- 8. Klickbare vs. reine Anzeige-Steps: aria-disabled für nicht erreichte Schritte
- 9. Umsetzung in Magento und Hyvä: generische Alpine.js-Wizard-Komponente
- 10. Zusammenfassung
- 11. FAQ
1. Das Wizard-Pattern als eigenständiges, allgemeines Problem
Mehrstufige Formulare treten in sehr unterschiedlichen Kontexten auf: Registrierungsassistenten mit mehreren Profil-Schritten, Produktkonfiguratoren mit aufeinander aufbauenden Auswahlschritten, mehrseitige Umfragen oder Support-Formulare mit bedingter Verzweigung. All diese Fälle teilen dieselbe technische Grundstruktur unabhängig vom konkreten Checkout-Kontext, weshalb sich das Wizard-Pattern als eigenständiges, wiederverwendbares Barrierefreiheitsthema behandeln lässt.
Vier Bausteine treten dabei immer wieder auf und müssen unabhängig voneinander korrekt umgesetzt werden: die semantische Gruppierung der Felder innerhalb eines Schritts, die visuelle und semantische Fortschrittsanzeige über alle Schritte hinweg, die aktive Ankündigung eines Schrittwechsels und der verlustfreie Umgang mit bereits eingegebenen Daten bei Vor- und Zurück-Navigation.
2. fieldset und legend: Gruppierung der Formularfelder pro Schritt
Jeder einzelne Schritt eines mehrstufigen Formulars sollte als eigenes fieldset-Element ausgezeichnet werden, mit einer legend, die den Zweck dieses Schritts kurz zusammenfasst, etwa "Schritt 2 von 4: Kontaktdaten". Diese Gruppierung ist mehr als reine Kosmetik, sie sorgt dafür, dass ein Screenreader beim Fokussieren des ersten Feldes im Schritt automatisch den Kontext des gesamten Schritts mit ansagt, nicht nur das einzelne Feldlabel.
Ohne fieldset/legend muss ein Nutzer sich den aktuellen Schritt-Kontext allein aus einzelnen Feldlabels erschließen, was besonders bei ähnlich benannten Feldern in verschiedenen Schritten, etwa mehreren Adressfeldern in unterschiedlichen Kontexten, schnell zu Verwechslungen führt.
<fieldset class="wizard-step" data-step="2">
<legend>Schritt 2 von 4: Kontaktdaten</legend>
<label for="email">E-Mail-Adresse</label>
<input type="email" id="email" name="email" required>
<label for="phone">Telefonnummer</label>
<input type="tel" id="phone" name="phone">
</fieldset>
3. Progress-Stepper Markup: aria-current für den aktuellen Schritt
Die Fortschrittsanzeige selbst wird üblicherweise als nav-Element mit einer geordneten Liste ol umgesetzt, in der jedes li einen Schritt repräsentiert. Der aktuell aktive Schritt bekommt das Attribut aria-current="step", einen speziellen, für genau diesen Anwendungsfall vorgesehenen Wert von aria-current, der sich von den generischeren Werten page oder true unterscheidet und Screenreadern explizit mitteilt, dass es sich um einen Schritt in einem sequenziellen Prozess handelt.
Bereits abgeschlossene Schritte sollten sich visuell und semantisch von noch nicht erreichten Schritten unterscheiden, etwa über einen zusätzlichen, versteckten Text wie "abgeschlossen" oder "noch nicht erreicht" innerhalb jedes Listenelements. Dieser Status darf nicht ausschließlich über eine Häkchen-Grafik oder eine Farbänderung kommuniziert werden, da beides ohne begleitenden Text für Screenreader unsichtbar bleibt.
<nav aria-label="Fortschritt">
<ol class="stepper">
<li>
<span class="sr-only">Abgeschlossen: </span>Konto
</li>
<li aria-current="step">
<span class="sr-only">Aktueller Schritt: </span>Kontaktdaten
</li>
<li>
<span class="sr-only">Noch nicht erreicht: </span>Adresse
</li>
<li>
<span class="sr-only">Noch nicht erreicht: </span>Bestätigung
</li>
</ol>
</nav>
4. Screenreader-Ankündigung von Schrittwechseln
Wechselt der Nutzer per Weiter-Button von einem Schritt zum nächsten, ändert sich in einer typischen Single-Page-Wizard-Implementierung nur der sichtbare Inhalt im DOM, ohne dass ein vollständiger Seitenwechsel stattfindet. Ohne aktive Ankündigung bemerkt ein Screenreader-Nutzer diesen Wechsel unter Umständen gar nicht, weil der Fokus an derselben Stelle verbleibt, an der sich zuvor der Weiter-Button befand.
Eine aria-live="polite"-Region, die bei jedem Schrittwechsel einen kurzen Text wie "Schritt 3 von 4: Adresse" ausgibt, macht den Wechsel zuverlässig hörbar. Diese Ankündigung ersetzt nicht das Fokus-Management aus dem nächsten Abschnitt, sondern ergänzt es, weil eine Live-Region auch dann wirkt, wenn der Fokus aus technischen Gründen kurzzeitig nicht exakt gesetzt werden kann.
<div id="step-announcement" class="sr-only" aria-live="polite"></div>
<script>
function goToStep(stepNumber, stepLabel, totalSteps) {
document.getElementById('step-announcement').textContent =
'Schritt ' + stepNumber + ' von ' + totalSteps + ': ' + stepLabel;
}
</script>
5. Fokus-Management beim Schrittwechsel: Fokus auf die Schritt-Überschrift setzen
Zusätzlich zur Live-Region-Ankündigung sollte der Tastaturfokus beim Schrittwechsel aktiv auf die Überschrift oder die legend des neuen Schritts gesetzt werden, meist per tabindex="-1" plus .focus() in JavaScript, da nicht-interaktive Elemente wie Überschriften standardmäßig nicht fokussierbar sind. Dieser Schritt stellt sicher, dass Tastaturnutzer nach dem Wechsel unmittelbar am Anfang des neuen Schritt-Inhalts weiterarbeiten können, statt manuell dorthin navigieren zu müssen.
Bleibt der Fokus stattdessen auf dem Weiter-Button des vorherigen Schritts stehen, der im neuen Schritt gar nicht mehr existiert oder an anderer Stelle liegt, verliert der Nutzer die Orientierung und muss den kompletten neuen Formularinhalt erst mit der Tab-Taste durchsuchen, um herauszufinden, was sich verändert hat.
function focusStepHeading(stepEl) {
const heading = stepEl.querySelector('legend, h2');
if (heading) {
heading.setAttribute('tabindex', '-1');
heading.focus();
}
}
6. Validierung pro Schritt vor dem Weiterschalten und Fehlerzusammenfassung
Ein Weiter-Klick sollte den aktuellen Schritt zunächst vollständig validieren, bevor zum nächsten Schritt gewechselt wird. Treten Fehler auf, darf der Schrittwechsel nicht stattfinden, und der Fokus muss auf eine Fehlerzusammenfassung am Anfang des aktuellen Schritts gesetzt werden, die alle fehlerhaften Felder als Liste mit Sprunglinks zum jeweiligen Feld aufführt.
Diese Fehlerzusammenfassung folgt demselben Muster wie bei einer einstufigen Formularvalidierung, wird hier aber pro Schritt wiederholt angewendet, da jeder Schritt faktisch ein eigenständiger Validierungsabschnitt ist. Wichtig ist, dass die Fehlermeldung eindeutig macht, in welchem Schritt der Fehler liegt, besonders wenn später eine Zusammenfassungsseite über alle Schritte hinweg Fehler sammelt.
7. Zwischenspeichern und Zurück-Navigation ohne Datenverlust
Navigiert ein Nutzer per Zurück-Button oder über einen klickbaren Schritt im Stepper zu einem vorherigen Schritt zurück, müssen bereits eingegebene Werte dort weiterhin vorhanden sein. Technisch lässt sich das entweder über einen clientseitigen State-Speicher, etwa einen Alpine-Store oder sessionStorage, oder über ein serverseitiges Zwischenspeichern bei jedem Schrittwechsel lösen, wobei Letzteres zusätzlich vor Datenverlust bei einem versehentlichen Browser-Neuladen schützt.
Aus Barrierefreiheitssicht ist entscheidend, dass die Zurück-Navigation keinen kompletten Neustart des Formulars auslöst, sondern exakt zum vorherigen Zustand samt aller eingegebenen Werte zurückkehrt, inklusive korrekt gesetztem Fokus auf die Schritt-Überschrift und korrekt aktualisiertem aria-current im Stepper. Ein Nutzer, der versehentlich einen Schritt zurückgeht, darf nicht dafür bestraft werden, bereits eingegebene Daten erneut eintippen zu müssen.
document.addEventListener('alpine:init', () => {
Alpine.data('wizard', () => ({
currentStep: 1,
values: Alpine.$persist({}).as('wizard-values'),
goTo(step) {
this.currentStep = step;
this.$nextTick(() => focusStepHeading(this.$refs['step-' + step]));
},
}));
});
8. Klickbare vs. reine Anzeige-Steps: aria-disabled für nicht erreichte Schritte
Ob Nutzer im Stepper direkt zu einem späteren, noch nicht erreichten Schritt springen dürfen, hängt vom jeweiligen Anwendungsfall ab. Ist ein direkter Sprung nicht sinnvoll, weil der spätere Schritt von Daten aus einem früheren, noch nicht validierten Schritt abhängt, sollte der entsprechende Stepper-Eintrag mit aria-disabled="true" markiert werden, statt ihn einfach optisch auszugrauen, ohne das semantisch zu kommunizieren.
Bereits abgeschlossene, frühere Schritte sollten dagegen fast immer klickbar bleiben, da Nutzer häufig noch einmal zurückspringen wollen, um eine Eingabe zu korrigieren. Ein klickbarer, bereits abgeschlossener Schritt-Eintrag sollte als button oder a-Element umgesetzt werden, nicht als reines li mit einem Klick-Handler ohne native interaktive Semantik.
9. Umsetzung in Magento und Hyvä: generische Alpine.js-Wizard-Komponente
Da das Wizard-Pattern nicht auf den Checkout beschränkt ist, lohnt sich eine generische Alpine.js-Komponente, die Schrittzustand, Validierung pro Schritt, Fokus-Management und die aria-live-Ankündigung kapselt und sich sowohl für einen Registrierungsassistenten als auch für einen Produktkonfigurator oder ein mehrstufiges Kontaktformular wiederverwenden lässt. Die konkreten Formularfelder je Schritt bleiben dabei austauschbar, während die Barrierefreiheitslogik zentral an einer Stelle gepflegt wird.
Jeder inline eingebundene script-Block für Fokus-Management oder Schrittwechsel-Ankündigung muss über $hyvaCsp->registerInlineScript() im jeweiligen phtml-Template registriert werden, damit die Content Security Policy die Ausführung nicht blockiert.
<div x-data="wizard" x-cloak>
<nav aria-label="Fortschritt">
<ol class="stepper">
<template x-for="(step, index) in steps" :key="step.id">
<li :aria-current="currentStep === index + 1 ? 'step' : null">
<span x-text="step.label"></span>
</li>
</template>
</ol>
</nav>
<div id="step-announcement" class="sr-only" aria-live="polite" x-text="announcement"></div>
</div>
| Baustein | Technik | Zweck | Häufiger Fehler |
|---|---|---|---|
| Feldgruppierung | fieldset plus legend pro Schritt | Kontext beim Fokussieren automatisch mit ansagen | Nur einzelne Feldlabels ohne Gruppen-Kontext |
| Fortschrittsanzeige | aria-current=step im Stepper | Aktuellen Schritt eindeutig kennzeichnen | Nur visuelle Hervorhebung ohne ARIA |
| Schrittwechsel | aria-live Region mit Schritt-Ansage | Wechsel ohne Seitenneuladen hörbar machen | Stiller DOM-Wechsel ohne Ankündigung |
| Fokus nach Wechsel | Fokus auf Überschrift des neuen Schritts | Direktes Weiterarbeiten ermöglichen | Fokus bleibt auf verschwundenem Button |
| Zurück-Navigation | State-Speicher pro Schritt | Eingegebene Werte erhalten | Formular startet beim Zurückgehen neu |
Mironsoft
WCAG-Audits, barrierefreie Magento-Shops und Schulungen
Unsicher, ob der Shop wirklich barrierefrei ist?
Wir prüfen bestehende Magento-Shops gegen WCAG 2.2, beheben konkrete Barrieren im Hyvä-Frontend und schulen Teams, damit Barrierefreiheit dauerhaft im Entwicklungsprozess verankert bleibt.
WCAG-Audit
Shop systematisch gegen WCAG 2.2 AA prüfen, mit priorisierter Fehlerliste.
Barrieren beheben
Konkrete Umsetzung: Tastaturbedienbarkeit, Screenreader-Support, Kontraste, Formulare.
Team-Schulung
Entwickler und Redakteure für barrierefreie Umsetzung im Alltag sensibilisieren.
10. Zusammenfassung
Mehrstufige Formulare barrierefrei: Die wichtigsten Fragen
Grundprinzip
fieldset und legend pro Schritt liefern automatisch Kontext, sobald ein Nutzer das erste Feld eines Schritts fokussiert.
Fortschrittsanzeige
aria-current=step markiert den aktuellen Schritt semantisch eindeutig, zusätzlich zu jeder visuellen Hervorhebung.
Schrittwechsel
Eine aria-live Ankündigung plus gezieltes Fokus-Management auf die neue Schritt-Überschrift machen jeden Wechsel nachvollziehbar.
Datenerhalt
Zurück-Navigation darf niemals bereits eingegebene Werte verwerfen, unabhängig davon, ob client- oder serverseitig gespeichert wird.