Tutorial
How to label form fields correctly
In short
Every input needs a visible <label> tied to the field's id via the for attribute. A placeholder is not a substitute: it disappears on input and is not reliably announced as the name. Required state and hints also belong in the text and are attached with required and aria-describedby.
At a glance
Tie the label to the field
Give each field an id and connect a <label> to it via the for attribute.
Do not use the placeholder as a label
The placeholder may only show an example, never be the only label.
Mark required fields
State the requirement in the visible label and also set the required attribute.
Attach hints
Link format or help text to the field with aria-describedby.
Missing or unconnected labels are one of the most common findings in automated scans because they break several success criteria at once. A screen reader reads a field with no label only as "edit text": the user has no idea what to enter.
The problem: placeholder instead of label
<!-- Placeholder statt Label: verschwindet beim Tippen, oft zu kontrastarm,
kein zuverlaessiger Name fuer Screenreader -->
<input type="email" placeholder="E-Mail-Adresse" />
<!-- Sichtbarer Text, aber nicht mit dem Feld verbunden -->
<span>Telefon</span>
<input type="tel" />- The placeholder disappears as soon as you type: the label is gone.
- Placeholder text often fails contrast (see 1.4.3 Contrast).
- Visible text next to a field with no for/id link is not announced as the name (1.3.1 / 4.1.2).
- Clicking the text does not focus the field.
The fix: a real label plus association
The label's for attribute points to the field's id. That makes the relationship programmatic (1.3.1), gives the field a name (4.1.2), and clicking the label focuses the field. The visible label text should be part of the accessible name (2.5.3 Label in Name), which this technique gives you automatically.
<label for="email">E-Mail-Adresse</label>
<input id="email" type="email" name="email" autocomplete="email" />
<!-- Pflichtfeld sichtbar UND programmatisch kennzeichnen -->
<label for="phone">Telefon (Pflichtfeld)</label>
<input id="phone" type="tel" name="phone" autocomplete="tel" required />
<!-- Zusatzhinweis mit aria-describedby anbinden -->
<label for="pw">Passwort</label>
<input id="pw" type="password" aria-describedby="pw-hint" />
<p id="pw-hint">Mindestens 12 Zeichen.</p>Required fields and hints
- Required: state it in the visible label (not only via a colour on an asterisk) and set required so software knows too (3.3.2).
- Format hints: attach them with aria-describedby so the screen reader reads them together with the field.
- Autocomplete: set the right autocomplete values (email, tel, name): it helps everyone and satisfies 1.3.5 Identify Input Purpose.
A purely visual required marker (just a red asterisk) is not enough: the information must also be in the text and the code. The same applies to errors, see our separate approach to error identification (3.3.1).
Related WCAG criteria
Frequently asked questions
- Is aria-label enough instead of a visible label?
- Only when a visible label is genuinely impossible (e.g. a search field with a magnifier icon). Visible labels help everyone, not just screen-reader users. When a visible label exists, its text must be part of the accessible name (2.5.3).
- Are placeholders forbidden?
- No. A placeholder may serve as an extra example (e.g. "name@company.com"), but never as the only label. Label and placeholder complement each other.
- How do I mark a required field accessibly?
- Put the requirement in the label text (e.g. "(required)") and set the required attribute. Do not rely on colour or an unexplained asterisk alone.
Request a free scan
Tell us your domain — we run a free initial scan and show you the most important barriers.