# Vague form labels that don't say what to enter

Source: https://easeweb.dev/learn/descriptive-labels
Topics: Forms > Form labels say what to enter (WCAG 2.4.6)
The fix: Say what to enter in each visible label. Either write the missing words into the label itself (Recipient's name, Date to send), or keep short labels inside a fieldset whose legend says whose details they are, and name anything the group doesn't explain, such as the date. Don't put the missing words only where screen readers get them.
Test with: screen reader
References: https://www.w3.org/WAI/WCAG22/Understanding/headings-and-labels.html https://www.w3.org/WAI/WCAG22/Techniques/general/G131 https://www.w3.org/WAI/WCAG22/Techniques/html/H71 https://www.w3.org/WAI/tutorials/forms/grouping/ https://webaim.org/techniques/forms/

This is a recreated teaching example, not a finding about a named client. The code is a starting pattern: test it in your own product. No completed assistive-technology test is claimed here.

## What happens

A shop's gift card page is drawn calm: a preview of the card, and beside it four fields in one column, each labelled with one word: Name, Email, Date and Message. The designer kept the labels short so the form looks light next to the card, and to them each word is plain enough: it is a gift form, so the name is the recipient's.

A visitor buying a card for a friend reads "Name" and types their own, because almost every form they have filled in asks for theirs. "Email" gets their own address too, so the card arrives in their inbox, not their friend's. "Date" could be the date to send it, the friend's birthday or the visitor's own date of birth, and only one of them is right. Nothing on the form says which; the confirmation email, or a friend who never got a card, is the first sign of the mix-up.

A second build of the same drawing keeps the one-word labels on screen and adds the missing words for screen readers only, in a visually hidden span. A screen reader user now hears "Name (recipient)". Everyone who reads the screen still sees Name.

## Why it fails

WCAG 2.4.6 Headings and Labels asks that headings and labels describe their topic or purpose. It doesn't ask for long labels: the Understanding page says a word, or even a single character, may be enough if it gives the right cue. But "Name" on a form that is about two people is not a cue to either of them, and "Date" fits three different answers. The labels exist and are tied to their fields, so the form passes 1.3.1 and 3.3.2; what fails is the words.

Hidden text doesn't change that. WCAG defines a label as text presented to the user to identify a component, and the label sighted visitors are presented with is still Name. The Trusted Tester test for 2.4.6 reviews the labels and instructions given for each field, and the ones on screen still don't say what to enter.

2.4.6 covers headings too; [headings chosen by size, not by structure](/learn/heading-structure) deals with those. This guide is about form labels.

## Who is affected

The guess is hardest where a form asks about two people, or two things of the same kind: gift cards, bookings made for someone else, delivery and billing addresses, an emergency contact. On a phone, the card preview that hints at the answer is pushed above or below the form, so even people who could have worked it out from the picture don't see it.

## What automation and AI miss

Every field has a label element tied to it, so axe, ANDI and every other label check pass the form. No rule can tell whether "Name" is the right word, because that depends on what this form asks. The EaseWeb audit sends a field labelled only with a word that rarely says enough on its own, such as Number, Date or Code, and two fields in one form with the same label and no legend apart, to a person as a lead to read, not as a failure. Asked to fix a vague label, AI coding tools can add `aria-label="Recipient's name"` or hidden text, which is the second Before below: the screen reader hears the purpose, and the screen still says Name.

## Before: one-word labels, as drawn

```html
<form>
  <label for="name">Name</label>
  <input id="name" name="recipient-name" type="text">

  <label for="email">Email</label>
  <input id="email" name="recipient-email" type="email">

  <label for="date">Date</label>
  <input id="date" name="send-date" type="date">

  <label for="message">Message</label>
  <textarea id="message" name="message"></textarea>

  <button type="submit">Buy gift card</button>
</form>
```

Every field is labelled, and every label is tied to its field. The code knows what each one is for, `recipient-name` and `send-date`; the labels people read say only Name and Date.

## Before: the missing words hidden for screen readers

```html
<form>
  <label for="name">Name <span class="visually-hidden">(recipient)</span></label>
  <input id="name" name="recipient-name" type="text">

  <label for="email">Email <span class="visually-hidden">(recipient)</span></label>
  <input id="email" name="recipient-email" type="email">

  <label for="date">Date <span class="visually-hidden">to send</span></label>
  <input id="date" name="send-date" type="date">

  <label for="message">Message</label>
  <textarea id="message" name="message"></textarea>

  <button type="submit">Buy gift card</button>
</form>
```

A screen reader says "Name (recipient), edit text", but the screen still shows Name, so everyone who reads the form rather than listening to it is still guessing.

## After: the missing words in each label

```html
<form>
  <label for="name">Recipient's name</label>
  <input id="name" name="recipient-name" type="text">

  <label for="email">Recipient's email</label>
  <input id="email" name="recipient-email" type="email">

  <label for="date">Date to send</label>
  <input id="date" name="send-date" type="date">

  <label for="message">Message</label>
  <textarea id="message" name="message"></textarea>

  <button type="submit">Buy gift card</button>
</form>
```

Each label now says what to enter on its own, wherever it is read: on screen, by a screen reader, in an error message ("Enter the recipient's email") or by voice control ("click Recipient's email"). The design keeps its single column, its type and its spacing; each label grows by a word or two and still fits one line at phone width. "Message" stays as it was: on a gift form, there is only one message it can mean.

## After: short labels under a legend that says whose they are

```html
<form>
  <fieldset>
    <legend>Who it's for</legend>

    <label for="name">Name</label>
    <input id="name" name="recipient-name" type="text">

    <label for="email">Email</label>
    <input id="email" name="recipient-email" type="email">
  </fieldset>

  <label for="date">Date to send</label>
  <input id="date" name="send-date" type="date">

  <label for="message">Message</label>
  <textarea id="message" name="message"></textarea>

  <button type="submit">Buy gift card</button>
</form>
```

This changes the look: a small heading, "Who it's for", sits over the name and email, and the two labels under it stay one word. The heading is the fieldset's `legend`, so it belongs to both fields in the code as well as on screen, and screen readers read it out with the fields: some once, some with every field, and only rarely not at all. The date sits outside the group, and no heading can say which date it is, so its label names it. Screen readers read the heading with the fields only while it is the `legend` of a `fieldset` around them; a heading styled to look the same, outside the fieldset, is seen above the fields but not read out with them.

## Which option to use

Both pass 2.4.6. Put the words in each label: it does the same job with no extra structure, and the label is the one piece of text that travels without its surroundings. An error summary, a "check your answers" page and voice control use the field's own label without the heading above it, so "Recipient's email" stays clear there and "Email" does not. Use a legend when a form asks the same things about two people or places, such as a gift form that also asks for the sender's name and email, or delivery and billing addresses, where "Recipient's" and "Your" in front of every label would make the form heavy; then write the group's words into the error messages and the review page yourself. Either way, a field that no group explains, like the date, needs its own words. Hidden text and `aria-label` are not a third option: they reach the screen reader and leave the screen as it was.

## Implementation decisions

The recipient's fields are not about the person filling in the form, so they take no `autocomplete="name"` or `autocomplete="email"`: the browser would offer the buyer's own details there, the same mix-up the vague label made. 1.3.5 asks for those tokens only on fields that collect information about the user; see [form fields that block or break autofill](/learn/autocomplete).

Keep the label for what the field is, and the format for a hint. "Date to send" says which date; how to type it, if the field isn't a native date input, goes in a line under the label tied to the field with `aria-describedby`. A placeholder is no place for either, because it disappears as soon as someone types.

A legend is read with the fields inside it, and some screen readers repeat it with each one, so keep it to a few words, "Who it's for", not a sentence of instructions. Put longer guidance in a paragraph before the group, tied to the first field with `aria-describedby` if it matters there.

In a shared field component, the label is a prop that a code review will pass whatever it says. Review label wording with the content, and keep the note on what each field holds next to the component's use, so the next person to edit the form can tell whether the label still fits.

## Verify the fix

1. Read each visible label on its own, without the heading or the card preview, together with its legend if it has one, write down what you would enter, and compare it with what the form expects.
2. Check that no two fields in the form share a label, unless each sits in a fieldset whose legend tells them apart.
3. With a screen reader, Tab through the form and open its list of form fields, and check that each field is announced with words that say what to enter, and that the same words are on screen.
4. Ask someone who hasn't seen the form to fill it in for a made-up friend, and check that every value lands in the field meant for it.

Record the OS, browser and assistive-technology versions, the build, the date, and the actual result of each step. Repeat when fields are added or relabelled, and when the form is translated.

## Limits

This is a starting pattern, not a guarantee for every application. It covers the words a label uses, not whether the label exists or is tied to its field ([form fields with missing or mismatched labels](/learn/form-labels)), how required fields are marked ([required fields marked only by colour](/learn/required-fields)), or the hints and formats a field may need beyond its label. Whether a label is clear depends on the people who use the form and what they already know, so test it with them, in every language the form ships in.

---

Get this guide in your coding agent: MCP https://easeweb.dev/mcp (setup at https://easeweb.dev/services/developers)
