Required fields, instructions & input purpose

Before a person types a single character, a form has already made promises about each field: this one is mandatory, that one wants a particular format, this one holds your own phone number. When those promises live only in the visual layer — a red asterisk a screen reader skips, a hint inside a placeholder that evaporates on the first keystroke, a name field the browser has no way to recognise — the user is left guessing. They submit, hit an error they were never warned about, and re-type data the browser already knew.

This lesson fixes three of the most common expectation defects. None of them needs new components or heavy ARIA: the required state belongs in the markup with required, instructions belong in persistent text tied to the field, and a field's purpose belongs in a standard autocomplete token. Wire those three in and the form tells everyone the same thing at the same time.

What you'll learn

How to mark a field required so it's announced as well as seen, without leaning on colour alone; how to give a field a persistent instruction tied with aria-describedby instead of a vanishing placeholder; and how to declare a personal-data field's purpose with the correct autocomplete token so it satisfies Identify Input Purpose and autofills for everyone.

Standards this lesson maps to
Standard Criterion Level What it requires
WCAG 2.2 3.3.2 Labels or Instructions A Labels or instructions are provided when content requires user input, including which fields are required and what format is expected.
WCAG 2.2 1.4.1 Use of Color A Colour is not the only visual means of conveying information — a required state can't be signalled by red alone.
WCAG 2.2 1.3.1 Info and Relationships A The required state and any instruction are conveyed in markup, not by visual presentation alone.
WCAG 2.2 1.3.5 Identify Input Purpose AA The purpose of each field collecting information about the user is programmatically determinable via autocomplete tokens.
WCAG 2.2 4.1.2 Name, Role, Value A A field's required state is exposed to assistive technology as part of its name, role, and value.
EN 301 549 9.3.3.2 / 9.1.3.5 (incorporates WCAG) European harmonised standard; references the WCAG A/AA set including labels, instructions, and input purpose.
Section 508 502.3 / 504 (incorporates WCAG A & AA) US federal ICT must meet WCAG 2.0 Level A and AA, including labels and instructions.
ADA Title II WCAG 2.1 AA (DOJ rule) AA US state/local government web content must conform to WCAG 2.1 AA, which includes 1.3.5 Identify Input Purpose.

The three problems we'll fix

Each card below isolates one common expectation defect. For every issue you get a plain-language statement of the problem, a Bad example (shown as escaped, non-running code so it can't harm this page), a Good example, the copyable Code, and an ordered fix.

Required state shown only by red colour

WCAG 2.2 · 3.3.2 A 1.4.1 A 4.1.2 A EN 301 549 Section 508

A label coloured red to mean "this field is required" carries the whole message in one channel: colour. Someone who can't perceive that red — a colour-blind user, anyone in high-contrast or forced-colours mode, a screen reader user — gets no signal at all that the field is mandatory (1.4.1). And because the colour is purely visual styling, the required state never reaches the accessibility tree, so the field is announced exactly like an optional one (4.1.2). The fix is two-sided: add the native required attribute so the state is programmatic, and pair the visual cue with text such as the word "required" or a visible asterisk that is explained once for the whole form.

Bad

Only a CSS class makes the label red. There is no required attribute and no text cue, so the requirement is invisible to anyone who can't see or distinguish the colour.

bad-required-colour.html
<style> .req { color: #d00; } </style>

<label for="email" class="req">Email</label>
<input type="email" id="email" name="email">

Good

The required attribute makes the state programmatic, so the field is announced as "required". A visible asterisk repeats the cue in a second channel, and a legend at the top of the form explains what the asterisk means.

good-required.html
<p id="req-note">Fields marked <span aria-hidden="true">*</span> are required.</p>

<label for="email">Email <span aria-hidden="true">*</span></label>
<input type="email" id="email" name="email" required aria-describedby="req-note">

Code

If a control can't use the native attribute (for example a custom widget), set aria-required="true" instead, and spell the word out in the visible label so the cue never depends on colour or a lone symbol.

aria-required.html
<label for="phone">Phone (required)</label>
<input type="tel" id="phone" name="phone" aria-required="true">

How to fix

  1. Add the native required attribute (or aria-required="true" on custom widgets) so the state reaches the accessibility tree.
  2. Pair any colour with a second cue — the word "required", or an asterisk that is explained once for the whole form.
  3. Explain the asterisk in visible text and reference it with aria-describedby; hide the decorative symbol itself with aria-hidden="true" so it isn't read as "star".
  4. Check in forced-colours / high-contrast mode that the requirement is still obvious, and confirm the field announces as "required".

Instructions placed only in the placeholder

WCAG 2.2 · 3.3.2 A 1.3.1 A EN 301 549 Section 508

When a field needs a rule — "at least 8 characters", "format DD/MM/YYYY", "use the name on your card" — and that rule lives only in the placeholder, it disappears the instant the user types. The person who most needs the reminder, someone with a memory or attention disability, loses it exactly when they start filling the field. Placeholder text is also low-contrast grey by default, isn't reliably announced as an instruction, and can be mistaken for a pre-filled value. An instruction that the form requires (3.3.2) has to be persistent and tied to the field in the markup (1.3.1) — usually a small line of help text linked with aria-describedby.

Bad

The format rule is hidden in the placeholder. It vanishes on the first keystroke and isn't programmatically associated with the field as an instruction.

bad-placeholder-instruction.html
<label for="pw">Password</label>
<input type="password" id="pw" name="pw"
       placeholder="At least 8 characters, 1 number">

Good

The instruction is a persistent line of text tied to the input with aria-describedby, so it stays on screen and is read after the label. The placeholder, if used at all, only shows an example format.

good-instruction.html
<label for="pw">Password</label>
<input type="password" id="pw" name="pw" aria-describedby="pw-help">
<p id="pw-help" class="field-hint">Use at least 8 characters and one number.</p>

Code

One field can reference several descriptions: list multiple ids in aria-describedby, separated by spaces, to combine a format hint with a current error. The hint stays; the error is added and removed as needed.

describedby-multiple.html
<label for="dob">Date of birth</label>
<input type="text" id="dob" name="dob"
       aria-describedby="dob-hint dob-error" aria-invalid="true">
<p id="dob-hint" class="field-hint">Format: DD/MM/YYYY.</p>
<p id="dob-error" class="error">Enter a real date, for example 24/05/1990.</p>

How to fix

  1. Move every rule the user must follow out of the placeholder and into visible help text near the field.
  2. Tie that text to the input with aria-describedby pointing at the hint's id, so it's announced after the label.
  3. Use placeholder at most for an example of the format — never as the only place an instruction appears.
  4. To combine a hint with an error, list both ids in aria-describedby separated by a space.
  5. Check the hint meets normal text-contrast requirements; don't leave it as faint placeholder-grey.

Personal-data field missing its autocomplete token

WCAG 2.2 · 1.3.5 AA EN 301 549 Section 508 ADA Title II

Identify Input Purpose (1.3.5) applies to any field that collects information about the user — their name, email, phone, address, birthday. Each such field must declare its purpose with one of the fixed autocomplete tokens from the HTML specification. With the right token the browser can autofill the value, assistive tools can present a familiar icon, and preference extensions can adapt the field — all of which spare people with cognitive, motor, or memory disabilities from recalling and re-typing their own data. A type="text" input with no token leaves that purpose undeclared, and the tokens are a controlled vocabulary, not free text.

Bad

These fields collect the user's own contact details but declare no purpose, so the browser can't map them and autofill is unreliable (1.3.5).

bad-no-token.html
<label for="fn">Full name</label>
<input type="text" id="fn" name="fn">

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

Good

Each field declares its purpose with the correct token. The type still drives the keyboard and validation; the autocomplete token satisfies 1.3.5 and enables autofill.

good-tokens.html
<label for="fn">Full name</label>
<input type="text" id="fn" name="fn" autocomplete="name">

<label for="em">Email</label>
<input type="email" id="em" name="em" autocomplete="email">

<label for="ph">Phone</label>
<input type="tel" id="ph" name="ph" autocomplete="tel">

Code

Tokens can be split for multi-part data and scoped to a contact type. Use autocomplete="off" only where autofill would genuinely be wrong, such as a one-time code.

token-vocabulary.html
<input autocomplete="given-name">       <!-- first name -->
<input autocomplete="family-name">      <!-- last name -->
<input autocomplete="street-address">
<input autocomplete="postal-code">
<input autocomplete="bday">             <!-- date of birth -->
<input autocomplete="work email">       <!-- scoped to work contact -->
<input autocomplete="one-time-code">    <!-- SMS code field -->

How to fix

  1. Add an autocomplete attribute to every field collecting the user's own data — name, email, phone, address, birthday, and so on.
  2. Use the exact tokens from the HTML autofill vocabulary (name, email, tel, given-name, postal-code, bday…), not invented values.
  3. Set the matching type too, so the right keyboard and validation appear on mobile.
  4. Reserve autocomplete="off" for fields where autofill is genuinely inappropriate; never use it to defeat password managers.

Recap

  • Mark required fields with the required attribute so the state is announced, and pair the visual asterisk with the word "required" or a legend — never colour alone (3.3.2, 1.4.1, 4.1.2).
  • Put instructions in persistent text tied to the field with aria-describedby; a placeholder vanishes on the first keystroke and can't carry the instruction (3.3.2, 1.3.1).
  • Declare every personal-data field's purpose with the correct autocomplete token from the HTML autofill vocabulary (1.3.5).

The same fixes satisfy WCAG, EN 301 549, Section 508, and ADA Title II at once — state the expectation in markup and you meet them all.