Komponenten · Formulare
Validierung & Pflichtfelder barrierefrei
Eine Pflichtangabe muss auf zwei Wegen erkennbar sein – sichtbar im Text des Labels und programmatisch über required. Für die Fehlermeldungen selbst reicht die eingebaute Browservalidierung nicht: Ihre Sprechblasen verschwinden von allein, zeigen nur das erste fehlerhafte Feld und lassen sich nicht gestalten.
Das ist die Stelle, an der viele Formulare kippen. Der Aufbau ist sauber, required steht dran, der Browser blockiert das Absenden – und trotzdem kommt jemand nicht durch, weil die Meldung weg ist, bevor sie gelesen werden konnte. Diese Seite trennt deshalb zwei Fragen: Welche Felder sind Pflicht, und wie melde ich Fehler so, dass sie ankommen?
Wie Fehlermeldungen formuliert werden, steht unter Fehlermeldungen barrierefrei; hier geht es um Kennzeichnung, Zeitpunkt und Ansage.
Das Wichtigste in Kürze
- Pflicht doppelt kennzeichnen: sichtbar im Label („Pflichtfeld“ oder ein erklärter Stern) und programmatisch über
required. Farbe allein genügt nie. -
requiredist unsichtbar. Es erzwingt die Eingabe und teilt den Zustand assistiven Technologien mit, ändert aber nichts an der Darstellung – die visuelle Kennzeichnung bleibt deine Aufgabe. - Die nativen Fehlersprechblasen sind keine barrierefreie Lösung. Sie blenden sich nach wenigen Sekunden selbst aus, zeigen nur das erste fehlerhafte Feld, sind nicht per CSS gestaltbar und in ihrer Ansage vom Browser abhängig.
- Der belastbare Weg:
requiredund die passendentype-Attribute setzen, das Formular mitnovalidateselbst prüfen und eine eigene, im DOM stehende Fehlerausgabe erzeugen. - Fehlerliste oben, Meldung am Feld. Eine Zusammenfassung mit Sprunglinks direkt unter der Überschrift plus eine Meldung je Feld ist das Muster, das mit Tastatur und Screenreader am zuverlässigsten funktioniert.
-
aria-invalid="true"erst setzen, wenn ein Fehler vorliegt – nicht vorsorglich beim Laden der Seite. - Zeitpunkt entscheidet über Frust. Prüfen beim Absenden, danach erneut beim Verlassen eines Feldes, das schon einmal beanstandet wurde. Nicht bei jedem Tastendruck.
- Tolerant annehmen: Telefonnummern mit Leerzeichen, IBANs in Vierergruppen. Und niemals das Einfügen blockieren – das sabotiert Passwortmanager.
- Betroffene Kriterien sind vor allem 3.3.1, 3.3.2 und 3.3.3; bei Kennzeichnung nur über Farbe zusätzlich 1.4.1.
Pflichtfelder kennzeichnen: sichtbar und programmatisch
Das native required-Attribut erledigt den programmatischen Teil komplett: Es verhindert das Absenden und gibt den Zustand an assistive Technologien weiter – Screenreader sagen dann „erforderlich“ oder „Pflichtfeld“ mit an.
<label for="name">Name (Pflichtfeld)</label>
<input type="text" id="name" name="name" required />
Das Wort „Pflichtfeld“ im Label ist die eindeutigste Kennzeichnung, weil sie in beiden Kanälen gleich ankommt. Sehr verbreitet ist auch das Sternchen. Das ist in Ordnung – es ist als Symbol etabliert –, braucht aber eine Erklärung an prominenter Stelle, denn von sich aus bedeutet * nichts:
<p id="pflicht-hinweis">Mit <span aria-hidden="true">*</span> markierte Felder sind Pflichtfelder.</p>
<label for="email">E-Mail <span aria-hidden="true">*</span></label>
<input type="email" id="email" name="email" required aria-describedby="pflicht-hinweis" />
Das aria-hidden="true" am Stern verhindert, dass er als „Stern“ oder „Asterisk“ vorgelesen wird – die Pflicht ergibt sich ohnehin aus required. Wer ein anderes Symbol wählt, muss es erklären; für den Stern gilt das aus Gewohnheit auch, aber weniger streng.
Drei Anforderungen gelten für die sichtbare Kennzeichnung, und die Handreichung des BFIT-Bund formuliert sie deutlich: Sie darf nicht allein über Farbe laufen, sie muss den Kontrastanforderungen genügen (4,5:1 als Text, 3:1 als grafisches Element), und sie muss im gesamten Angebot konsistent sein. Der letzte Punkt ist der, den große Websites verlieren: Auf der Kontaktseite steht „(Pflichtfeld)“, im Checkout ein Stern, in der Registrierung nichts.
Reicht das native Attribut einmal nicht – etwa bei einem mit ARIA nachgebauten Bedienelement – übernimmt aria-required="true" dieselbe Aussage, allerdings ohne die Browservalidierung.
Pflicht oder optional – was kennzeichnen?
Eine kleine Designfrage mit großer Wirkung: Markiert man die Pflicht- oder die optionalen Felder? Meine Regel ist pragmatisch – ich kennzeichne, was in der Minderheit ist. Sind die meisten Felder Pflicht, hebe ich die wenigen optionalen mit „(optional)“ hervor; ist es umgekehrt, markiere ich die Pflichtfelder. Das spart visuelles Rauschen und macht das Wichtige sichtbar.
Wichtig ist nur, dass die Entscheidung im Formular durchgehalten wird und dass die Regel irgendwo steht. Felder ganz ohne jede Kennzeichnung sind immer ein Ratespiel – und zwar für alle, nicht nur für Screenreader-Nutzung.
Die Grenzen der nativen Fehlermeldungen
HTML bringt eine erstaunlich fähige Constraint-Validierung mit. Sie ist als Fundament richtig: Sie funktioniert ohne JavaScript, kennt Typen, Muster und Grenzwerte und liefert kostenlos die programmatische Kennzeichnung. Nur ihre Fehlerausgabe ist unbrauchbar, sobald man Barrierefreiheit ernst nimmt. Vier Gründe:
- Sie verschwindet von allein. Die Sprechblase blendet sich nach wenigen Sekunden aus. Wer langsamer liest, vergrößert oder erst zur Stelle navigieren muss, findet sie nicht mehr.
- Sie zeigt nur das erste fehlerhafte Feld. Bei fünf Fehlern muss man fünfmal absenden, um alle zu sehen.
- Sie ist nicht gestaltbar. Größe, Kontrast, Schrift und Position bestimmt der Browser. Bei starkem Zoom rutscht sie regelmäßig aus dem sichtbaren Bereich.
- Sie ist nicht dein Text. Formulierung und Sprache kommen vom Browser und passen selten zu dem, was das Feld eigentlich verlangt.
Genau darauf weist die Handreichung des BFIT-Bund zur Pflichtfeldkennzeichnung hin, und es deckt sich mit dem, was mir in Tests begegnet: Die Kombination „required plus Browsermeldung“ sieht in der Entwicklung geprüft aus und fällt in der Nutzung durch. Ich würd sie deshalb nur dort stehen lassen, wo gar kein JavaScript im Spiel ist.
Der belastbare Aufbau
In der Praxis sieht der Weg so aus: native Attribute für die Semantik, eigene Prüfung für die Ausgabe. Das Formular bekommt novalidate, damit der Browser die Sprechblasen unterdrückt – die Constraint-Validierung selbst bleibt über die JavaScript-API verfügbar.
<form novalidate>
<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, z. B. 10115.</a></li>
</ul>
</div>
<p>
<label for="plz">Postleitzahl (Pflichtfeld)</label>
<input
type="text"
id="plz"
name="plz"
inputmode="numeric"
pattern="\d{5}"
required
autocomplete="postal-code"
aria-describedby="plz-hilfe plz-fehler"
aria-invalid="true"
/>
<span id="plz-hilfe">Fünf Ziffern, z. B. 10115.</span>
<span id="plz-fehler" class="fehler">Bitte fünf Ziffern eingeben.</span>
</p>
<button type="submit">Absenden</button>
</form>
Vier Details entscheiden hier über die Zugänglichkeit:
- Die Fehlerliste steht oben und trägt
tabindex="-1", damit der Fokus nach dem Absenden dorthin gesetzt werden kann. Ein Fokuswechsel ist zuverlässiger als jede Live-Region, weil er die Ansage nicht dem Timing überlässt. - Jeder Listeneintrag ist ein Link auf das betroffene Feld. Mit Tastatur ist man damit in einem Tastendruck an der Stelle, an der etwas fehlt.
-
aria-describedbyverweist auf Hilfetext und Fehlermeldung – beide IDs, durch Leerzeichen getrennt. Der Screenreader liest sie zum Feld mit. -
aria-invalid="true"steht nur an fehlerhaften Feldern. Setzt man es vorsorglich beim Laden, ist von Anfang an alles „ungültig“, und die Information wird bedeutungslos.
Die eigentliche Prüfung darf ruhig auf die eingebaute API zurückgreifen – man muss keine E-Mail-Regex schreiben:
const form = document.querySelector('form');
form.addEventListener('submit', (e) => {
const fehlerhaft = [...form.elements].filter((el) => el.willValidate && !el.checkValidity());
if (fehlerhaft.length === 0) return;
e.preventDefault();
fehlerhaft.forEach(markiereFehler);
const liste = document.getElementById('fehlerliste');
liste.hidden = false;
liste.focus();
});
checkValidity() liefert das Urteil, validity sagt genauer, woran es lag – valueMissing, patternMismatch, typeMismatch. Daraus lassen sich Meldungen bauen, die sagen, was zu tun ist, statt nur festzustellen, dass etwas nicht passt. Das ist übrigens der Unterschied zwischen 3.3.1 Fehlererkennung und 3.3.3 Fehlervorschlag: Ersteres verlangt, den Fehler zu benennen, Letzteres einen Vorschlag zur Behebung.
Falls du ohne eigenes JavaScript arbeitest, ist das native Verhalten immer noch besser als keine Validierung – dann aber unbedingt mit Hilfetexten neben den Feldern, damit das erwartete Format vorab klar ist. Probier den Unterschied direkt aus:
Live-Beispiel: native Validierung
Drei Dinge erledigt dieses Beispiel nebenbei: inputmode="numeric" blendet auf dem Smartphone die Zifferntastatur ein, pattern definiert das erlaubte Format, und autocomplete="postal-code" lässt den Browser bekannte Werte einsetzen. Gerade autocomplete unterschätzen viele – es hilft allen und erfüllt zugleich 1.3.5 Eingabezweck bestimmen.
Fair prüfen: Zeitpunkt und Toleranz
Wie und wann geprüft wird, entscheidet darüber, ob Validierung unterstützt oder gängelt.
- Nicht bei jedem Tastendruck. Eine E-Mail als „ungültig“ zu melden, während man beim zweiten Buchstaben ist, frustriert nur. Ich prüfe beim Absenden – und danach erneut beim Verlassen eines Feldes, das schon einmal beanstandet wurde. Dieses Muster nennt sich „validate on submit, revalidate on blur“ und ist der beste Kompromiss, den ich kenne.
- Erfolge nicht ansagen. Ein grünes Häkchen mit Live-Region-Meldung bei jedem korrekt gefüllten Feld erzeugt eine Geräuschkulisse, die niemandem hilft.
- Eingaben tolerant entgegennehmen. Telefonnummern mit Leerzeichen, IBANs in Vierergruppen, Namen mit Bindestrich oder Apostroph: Was eindeutig gemeint ist, sollte akzeptiert und intern normalisiert werden, statt zurückgewiesen zu werden. Das gilt auch für führende und folgende Leerzeichen – die entstehen beim Einfügen fast immer.
- Niemals das Einfügen blockieren.
onpastezu unterbinden – gern bei Passwort- oder E-Mail-Feldern gesehen – ist eine echte Barriere, gerade für Passwortmanager und für Menschen, die mit Sprachsteuerung oder einer Hilfstastatur arbeiten. - Maxlength mit Bedacht. Ein hartes Zeichenlimit ohne Rückmeldung wirkt wie eine defekte Tastatur. Wenn ein Limit nötig ist, gehört ein Zähler dazu.
Diese Toleranz ist kein Komfort-Extra. Wer Eingaben unnötig streng formatiert, sperrt reale Menschen aus – und das widerspricht dem Grundgedanken der vier Prinzipien der WCAG.
Bei folgenreichen Vorgängen kommt noch eine Stufe dazu: 3.3.4 Fehlervermeidung verlangt für rechtsverbindliche, finanzielle und datenlöschende Aktionen, dass Eingaben umkehrbar, geprüft oder bestätigt werden. Ein Bestellabschluss braucht also eine Zusammenfassung mit Korrekturmöglichkeit, kein „Absenden“ ohne Rückweg.
Zusammenspiel mit Gruppen
Auch eine Gruppe kann Pflicht sein – etwa „mindestens eine Option wählen“ oder eine Einwilligung aus mehreren Checkboxen. Die Kennzeichnung gehört dann in die <legend>, nicht an ein einzelnes Feld, und die Fehlermeldung an das <fieldset>. Wie du solche Gruppen aufbaust, steht unter fieldset & legend.
Bei Radiobuttons ist zusätzlich zu beachten: required an einem Radio der Gruppe wirkt für die ganze Gruppe – aber die Fehlermeldung darf nicht an einem einzelnen Radio hängen, sonst findet sie niemand.
Häufige Fehler
- Pflichtfelder nur per Farbe markiert. Ohne Text oder
requiredbleibt die Pflicht für viele unsichtbar – und verstößt gegen 1.4.1 Benutzung von Farbe. - Stern ohne Legende. Ein
*allein sagt nichts. - Nur die native Sprechblase. Verschwindet, zeigt einen Fehler, ist nicht gestaltbar.
-
aria-invalid="true"von Anfang an. Macht die Angabe wertlos. - Validierung bei jedem Tastendruck. Meldet Fehler, bevor die Eingabe fertig ist.
- Zu strenge Formate. Leerzeichen oder Bindestriche werden abgelehnt, obwohl die Eingabe eindeutig ist.
- Einfügen blockiert. Sabotiert Passwortmanager und Kopieren.
- Absenden-Button dauerhaft deaktiviert, bis alles stimmt – verrät nicht, was fehlt.
Häufige Fragen
required oder aria-required?
Wo immer es geht required: Es kennzeichnet das Feld und erzwingt die Eingabe. aria-required="true" nutzt du nur, wenn das native Attribut nicht greift, etwa bei einem mit ARIA nachgebauten Bedienelement. Beides zugleich ist unnötig und in seltenen Fällen widersprüchlich.
Soll ich novalidate wirklich setzen?
Wenn du eine eigene Fehlerausgabe baust: ja. novalidate unterdrückt nur die Browsersprechblasen, nicht die Validierung selbst – checkValidity() und validity funktionieren weiter. Ohne eigene Ausgabe lass es weg; dann ist die native Meldung besser als keine.
Soll ich das Absenden deaktivieren, bis alles stimmt?
Davon rate ich ab. Ein dauerhaft ausgegrauter Button verrät nicht, was fehlt, und ist mit Tastatur und Screenreader schwer zu deuten. Besser: absenden lassen, prüfen, klar zurückmelden – mit Fehlerliste oben und Fokus darauf.
Wie sage ich Fehler einem Screenreader an?
Zuverlässig über einen Fokuswechsel auf die Fehlerliste, die role="alert" und tabindex="-1" trägt. Reine Live-Regionen funktionieren auch, sind aber empfindlicher: Der Container muss vor dem Einfügen des Textes im DOM stehen. Mehr dazu unter Live-Regionen.
Muss ich Eingaben trotzdem serverseitig prüfen?
Unbedingt. Clientseitige Validierung ist Komfort, keine Sicherheit – sie lässt sich umgehen. Die verbindliche Prüfung passiert immer auf dem Server, und ihre Fehlermeldungen brauchen genau dieselbe Behandlung wie die im Browser.
Fazit
Barrierefreie Validierung heißt: Pflicht doppelt kennzeichnen, die native Constraint-Validierung als Fundament nutzen, ihre Sprechblasen aber durch eine eigene, dauerhaft sichtbare Ausgabe ersetzen – Fehlerliste oben mit Sprunglinks, Meldung am Feld, aria-invalid nur im Fehlerfall. Dazu ein Prüfzeitpunkt, der nicht ins Tippen hineinredet, und Toleranz gegenüber allem, was eindeutig gemeint ist. Wie die Meldungen selbst formuliert werden, steht unter Fehlermeldungen barrierefrei; das Zusammenspiel über mehrere Schritte unter Mehrstufige Formulare.
Quellen
- Pflichtfeldkennzeichnung (Handreichung des BFIT-Bund – normative Anforderungen, Screenreader-Ausgaben, Grenzen von
required) - Formularvalidierung (MDN – Constraint-Validation-API,
novalidate,validity)