3.3.2 Labels or Instructions

Level: A | Principle: Understandable | Since: WCAG 2.0 | Automation: Partial (axe-core)


What This Means

When a form field requires user input, it must have a label that describes what to enter. Without labels, screen reader users have no idea what a text field, dropdown, or checkbox is asking for.

Who This Affects

  1. Screen reader users — an unlabeled input is announced as "edit text" with no context
  2. Voice control users — they say "click [label text]" to interact with fields
  3. Cognitive disability users — clear labels reduce confusion
  4. Everyone — clicking a label focuses the associated input (better UX)

Common Pitfalls

1. No label at all

<!-- Bad: input with no label -->
<input type="text">

<!-- Bad: visual text near the input but not associated -->
<span>Email</span>
<input type="email">

2. Placeholder as the only label

<!-- Bad: placeholder disappears when typing -->
<input type="email" placeholder="Email address">

<!-- Good: proper label + placeholder for extra hint -->
<label for="email">Email address</label>
<input id="email" type="email" placeholder="name@example.com">

3. Label not associated with the input

<!-- Bad: label exists but no for/id connection -->
<label>Email</label>
<input type="email">

<!-- Good: for matches id -->
<label for="email">Email</label>
<input id="email" type="email">

4. Multiple labels on one input

<!-- Bad: confusing for assistive technology -->
<label for="name">Name</label>
<label for="name">Your full name</label>
<input id="name" type="text">

How to Fix

Explicit label (recommended)

<label for="phone">Phone number</label>
<input id="phone" type="tel">

Implicit label (wrapping)

<label>
  Phone number
  <input type="tel">
</label>

When a visible label isn't possible

<!-- Search field with visible button — use aria-label -->
<input type="search" aria-label="Search this site">
<button>Search</button>

Required fields

<label for="email">
  Email address <span aria-hidden="true">*</span>
  <span class="sr-only">(required)</span>
</label>
<input id="email" type="email" required aria-required="true">

How to Test

  1. Tab through every form field on the page using a screen reader and verify each field has a label announced when it receives focus.
  2. Click on each visible label text and confirm it focuses the associated input field (verifying the for/id connection works).
  3. Check for inputs that use only placeholder text as a label. Placeholders disappear on input and are not reliable labels.
  4. Verify required fields are indicated with text (e.g., "(required)" or asterisk with explanation) not just color.
  5. Pass: Every form field has a visible, programmatically associated label, and required fields are indicated in text.
  6. Fail: Any field lacks a label, uses only placeholder as a label, has a label not associated via for/id, or indicates required status by color alone.

axe-core Rules

| Rule | What It Checks | |------|---------------| | label | Form elements must have labels | | form-field-multiple-labels | Form fields should not have multiple labels |

Sources

  1. W3C WCAG 2.2 — Understanding 3.3.2
  2. axe-core: label
  3. W3C Form Labels Tutorial