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
- Screen reader users — an unlabeled input is announced as "edit text" with no context
- Voice control users — they say "click [label text]" to interact with fields
- Cognitive disability users — clear labels reduce confusion
- 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
- Tab through every form field on the page using a screen reader and verify each field has a label announced when it receives focus.
- Click on each visible label text and confirm it focuses the associated input field (verifying the
for/idconnection works). - Check for inputs that use only
placeholdertext as a label. Placeholders disappear on input and are not reliable labels. - Verify required fields are indicated with text (e.g., "(required)" or asterisk with explanation) not just color.
- Pass: Every form field has a visible, programmatically associated label, and required fields are indicated in text.
- 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 |