Barrierefreie Komponenten · Formulare

Labels & Beschriftungen für Formulare

Ein Formularfeld ohne Beschriftung ist eine Rückfrage. Wer es ausfüllen soll, muss raten, was hineingehört – und wer einen Screenreader nutzt, hört im Zweifel nur „Eingabefeld“, ganz ohne Hinweis. Das <label>-Element löst das auf die denkbar einfachste Weise: Es verbindet einen sichtbaren Text fest mit einem Bedienelement.

Diese Verbindung ist mehr als Kosmetik. Ein korrekt verknüpftes Label vergrößert die Klickfläche, liefert assistiven Technologien den zugänglichen Namen des Feldes und überlebt jede spätere Umgestaltung. Beschriftungen gehören für mich zu den Dingen, bei denen sich der geringste Aufwand am deutlichsten auszahlt – und trotzdem sehe ich sie ständig falsch oder gar nicht umgesetzt.

Warum jedes Feld eine Beschriftung braucht

Sobald Software ein Formular interpretieren muss, wird die Beschriftung zum zentralen Anker. Drei Effekte hängen direkt daran:

  • Verständlichkeit: Ein Screenreader liest beim Fokussieren des Feldes dessen zugänglichen Namen vor. Fehlt er, bleibt das Feld stumm oder bekommt einen generischen Platzhalternamen.
  • Bedienbarkeit: Ein verknüpftes Label ist Teil der Trefferfläche. Ein Klick oder Tap auf den Text setzt den Fokus ins Feld bzw. schaltet eine Checkbox – ein echter Gewinn besonders auf dem Smartphone.
  • Robustheit: Die Zuordnung steht im Markup, nicht in der optischen Nähe. Sie bleibt also korrekt, egal wie das Layout später verschoben wird.

Die WCAG fassen das in zwei Kriterien: Jedes Bedienelement braucht ein sichtbares Label (3.3.2) und einen programmatisch ermittelbaren Namen (4.1.2). Mit nativem HTML erfüllst du beide in einer Zeile.

Die zwei Wege, ein Label zu verknüpfen

Es gibt genau zwei korrekte Muster. Beide sind valide – ich greife in der Praxis aber fast immer zur ersten Variante.

Explizit über for und id – das Label verweist per for auf die id des Feldes:

<label for="email">E-Mail-Adresse</label>
<input type="email" id="email" name="email" autocomplete="email" />

Implizit durch Umschließen – das Feld liegt im <label>:

<label>
  E-Mail-Adresse
  <input type="email" name="email" autocomplete="email" />
</label>

Die explizite Variante hat zwei Vorteile, die mir den Ausschlag geben: Sie lässt Text und Feld im Markup frei anordnen (wichtig für viele Layouts), und sie funktioniert zuverlässiger mit älteren Hilfsmitteln. Die id muss dabei pro Seite eindeutig sein – bei generierten Formularen ein häufiger Stolperstein.

Ein verbreiteter Irrtum: placeholder sei ein Label. Ist es nicht. Der Platzhalter verschwindet beim Tippen, hat oft zu wenig Kontrast und wird von manchen Screenreadern gar nicht als Name gewertet. Nutze ihn höchstens als ergänzendes Beispiel („z. B. max@example.com“), nie als Ersatz für das Label.

Wenn kein sichtbares Label möglich ist

Manchmal verlangt das Design ein Feld ohne sichtbaren Text – das klassische Suchfeld mit Lupensymbol etwa. Auch dann braucht das Feld einen Namen. Drei Wege führen zum Ziel, in meiner bevorzugten Reihenfolge:

<!-- 1. Bevorzugt: sichtbares <label>, nur optisch ausgeblendet -->
<label class="visually-hidden" for="suche">Suche</label>
<input type="search" id="suche" name="q" />

<!-- 2. aria-label, wenn ein echtes Label nicht praktikabel ist -->
<input type="search" name="q" aria-label="Suche" />

<!-- 3. aria-labelledby, wenn ein vorhandener Text das Feld benennt -->
<h2 id="newsletter-titel">Newsletter abonnieren</h2>
<input type="email" name="email" aria-labelledby="newsletter-titel" />

Ich nehme das visuell versteckte <label> (.visually-hidden) den ARIA-Attributen gegenüber bewusst vor: Es ist echter Text, wird von Übersetzungs-Tools mitübersetzt und lässt sich nicht so leicht übersehen. aria-label ist die solide zweite Wahl – kein sichtbarer Text, der versehentlich unübersetzt bleibt. Das passt zur ersten Regel von ARIA: natives HTML zuerst, ARIA nur, wo es wirklich nötig ist.

Beschriftungen, die wirklich helfen

Ein verknüpftes Label ist die halbe Miete – die andere Hälfte ist sein Wortlaut. Ein paar Punkte, auf die ich achte:

  • Knapp und eindeutig. „E-Mail-Adresse“ ist besser als „Bitte geben Sie hier Ihre E-Mail-Adresse ein“. Die Aufforderung steckt schon im Feld.
  • Zusatzhinweise nicht ins Label, sondern daneben. Formatregeln oder Beispiele gehören in einen separaten Text, der über aria-describedby mit dem Feld verbunden wird – so bleiben Name und Hilfetext getrennt.
<label for="pw">Passwort</label>
<input type="password" id="pw" aria-describedby="pw-hilfe" />
<p id="pw-hilfe">Mindestens 12 Zeichen, mit Zahl und Sonderzeichen.</p>

Genau dieses aria-describedby-Muster trägt später auch die Fehlermeldungen und die Kennzeichnung von Pflichtfeldern. Es lohnt sich, es einmal sauber zu verstehen.

Gruppen brauchen eine eigene Beschriftung

Ein einzelnes <label> benennt genau ein Feld. Mehrere zusammengehörige Felder – etwa die Radio-Buttons einer Frage – brauchen zusätzlich eine übergeordnete Beschriftung. Dafür gibt es <fieldset> und <legend>, die ich auf der Seite fieldset & legend ausführlich behandle.

Häufige Fehler

  • placeholder statt label. Der häufigste Fehler überhaupt – und für mich ein echter Klassiker des „sieht hübsch aus, funktioniert aber nicht“.
  • Label nicht verknüpft. Ein <label> ohne for (oder ohne Umschließen) ist nur Text daneben. Die programmatische Verbindung fehlt.
  • Doppelte oder fehlende id. for zeigt dann ins Leere oder auf das falsche Feld.
  • Nur eine Grafik als Beschriftung. Ein Icon ohne Textalternative benennt nichts – siehe Icons & SVGs.
  • Sichtbares Label und abweichendes aria-label. Spracheingabe-Nutzer sagen „Klick E-Mail“, treffen aber den unsichtbaren Namen nicht. Sichtbarer Text und zugänglicher Name sollten übereinstimmen (WCAG 2.5.3, „Label in Name“).

Häufige Fragen

Reicht ein aria-label nicht völlig aus?

Technisch benennt es das Feld, ja. Sehende Nutzer ohne Screenreader sehen dann aber gar keine Beschriftung. Ein sichtbares Label hilft allen – darum ist es die erste Wahl, und aria-label nur der Notnagel.

Muss jedes Feld ein eigenes Label haben?

Ja. Auch Checkboxen, Radio-Buttons und <select> brauchen je ein verknüpftes Label. Ein Datumsbereich aus zwei Feldern bekommt zwei Labels („von“ / „bis“), zusammengehalten von einer Gruppen-Beschriftung.

Wie beschrifte ich einen Button?

Bei einem <button> ist der sichtbare Textinhalt zugleich der Name – ein zusätzliches <label> ist weder nötig noch vorgesehen. Worauf es bei Buttons ankommt, steht unter Buttons vs. Links.

Fazit

Beschrifte jedes Feld mit einem verknüpften <label> – explizit über for/id, sichtbar wo immer möglich. Das ist die wichtigste und billigste Maßnahme für zugängliche Formulare. Alles Weitere, von Pflichtfeldern über Fehlermeldungen bis zu Feldgruppen, baut auf dieser einen sauberen Verbindung auf. Wenn ich ein Formular prüfe, ist es das Erste, wonach ich schaue.