( Understandable / WCAG 3.3.2 )
Form field has more than one label
What is this issue?
A single form control (an <input>, <select>, or <textarea>) has more than one <label> element associated with it at once. This usually happens through a combination of a wrapping label (the input nested inside <label>...</label>) and a separate <label for> pointing at the same input’s id, or occasionally two separate for labels both targeting the same id by mistake.
Both associations are individually valid HTML: a wrapping label and a for/id label are each a correct way to build a programmatic label, a label connected to its control in the underlying code, not just visually next to it. The problem is having both at once on the same field.
Why does this matter?
When a form control has multiple associated labels, most browsers compute its accessible name by concatenating the text of every associated label, in DOM order, into one string. A field meant to be labeled “Email” that also has a second, redundant label saying “Enter your email” doesn’t announce as either; it announces as something closer to “Email Enter your email,” a duplicated, oddly-phrased name nobody wrote on purpose.
This is confusing rather than catastrophic on its own, but it compounds with every other field on the form built the same way, and it signals a deeper markup problem: whoever built the form doesn’t have a single, deliberate source of truth for what each field is called. The visible label a sighted user reads and the accessible name a screen reader announces can end up saying different things once concatenation is involved, which is exactly the kind of small inconsistency that erodes trust in a form users are trying to complete correctly the first time.
Who is affected?
- Screen reader users: hear a concatenated, duplicated, or oddly-ordered name instead of the field’s real label, making it harder to quickly confirm which field they’re in, especially on a long or unfamiliar form.
- Cognitive disabilities: users who rely on a short, clear, predictable name to keep their place in a form are slowed down by a garbled double-announcement that doesn’t match the shorter text they can see on screen.
What users experience
Diego uses NVDA on his Windows laptop to fill out a newsletter signup form built from a shared input component that wraps every field in a <label> for convenience. A separate section of the form was hand-coded later with an explicit <label for="email">Email address</label>, unaware the input was already label-wrapped with the text “Enter your email below.” NVDA announces “Email address, Enter your email below, edit text,” a run-on phrase Diego has to parse before he’s confident he’s found the right field, on a form the visible design shows as a single, tidy “Email address” label.
How do I fix it?
Keep exactly one <label> associated with each form control and delete the rest. This works because the accessible-name computation only produces a clean, predictable result when there’s a single source to read from: removing the duplicate eliminates the concatenation entirely rather than trying to control its order.
Before deleting, read both labels’ text first. If one label contains information the other doesn’t (a format hint, a “required” marker), fold that wording into the single label you keep, or move it into separate visible instruction text linked with aria-describedby, rather than silently losing it. Once you’re down to one label, verify it reads as a complete, accurate name on its own.
Code Examples
<label for="email">Email address</label>
<label>
<input id="email" type="email">
Enter your email
</label><label for="email">Email address</label>
<input id="email" type="email">The fixed version keeps only the for/id label and removes the redundant wrapping label entirely, so the input’s accessible name resolves to a single, clean “Email address” instead of two label texts concatenated together.
Common Mistakes
Mistake: “More labeling is always safer than less.” This intuition holds for most accessibility fixes but not this one: a second label doesn’t add clarity, it triggers concatenation and produces a less clear name than either label would give alone. One accurate label beats two overlapping ones every time.
Mistake: “The visible page looks fine, so the markup underneath must be fine too.” A wrapping <label> and a separate for label can both render visually in a way that looks like one clean label on screen, since CSS controls layout independently of the DOM relationships underneath. The duplication is invisible until you check the accessible name directly, not the rendered page.
Mistake: “I’ll just delete whichever label element I find first.” Deleting the wrong one, or deleting without reading both first, risks losing wording that mattered: a “required” marker, a subtly different phrasing that was actually more accurate. Read both, keep the more complete and accurate one, and fold in anything the other said that’s worth keeping.
How RedFlag Detects This
Automated: axe-core rule, runs on every scan. RedFlag calls axe-core’s form-field-multiple-labels rule as part of every scan, restricted to the WCAG 2.0/2.1/2.2 A and AA rule set. The rule inspects every labelable form control and counts how many <label> elements resolve to it, through wrapping, for/id, or both, flagging any field with more than one.
False negative: the check only counts <label> elements; it doesn’t flag a field that has one <label> plus a conflicting aria-labelledby reference producing a similarly garbled name through a different mechanism. False positive: none typical for this check, since counting associated <label> elements per control is a straightforward DOM query axe-core evaluates reliably. Manual step: listen to the field’s actual announced name in a screen reader after your fix, since removing one label doesn’t guarantee the remaining one is a complete, accurate name on its own.
Manual Testing
- Open the page in Chrome or Firefox with NVDA or JAWS running.
- Tab to each form field and listen to the full name announced immediately after the role.
- If the announcement sounds duplicated, run-on, or includes text you don’t recognize from the visible label, inspect the field’s markup for a second
<label>element. - Open the browser’s accessibility inspector (Chrome DevTools → Elements → Accessibility pane) and confirm the “Name” property matches the single visible label text exactly, with no repeated or concatenated wording.
Related WCAG Success Criteria
3.3.2 Labels or Instructions: Labels or instructions must be provided when content requires user input. Multiple conflicting labels technically satisfy “a label exists” while undermining the clarity this criterion is really protecting; a label that’s present but confusing does not meet the spirit of the requirement.
Related Issues
Form input has no label is the opposite failure mode (zero labels instead of too many), but shares the same underlying goal of giving every field exactly one clear, programmatic name.
Related form inputs are missing fieldset and legend covers a different multi-field labeling problem: grouped inputs needing one shared group name via <fieldset>/<legend> rather than stretching or duplicating individual <label> elements.
Input only uses placeholder as its label is a related labeling failure on the opposite end of the spectrum: a placeholder standing in for a label that was never built at all.
Form field autocomplete attribute is missing or invalid covers a separate, machine-readable identification requirement for the same input types this rule affects: a correctly labeled field can still fail autofill identification independently.
Form error is not clearly identified covers a related trust-eroding form problem: unclear error targeting rather than unclear field naming, but the same class of small markup gap that undermines a form’s usability.
References
- W3C Understanding 3.3.2: Labels or Instructions
- W3C Technique H44: Using label elements to associate text labels with form controls
- MDN: The Label element
Frequently asked questions
Why would a field ever end up with two labels by accident?
The most common cause is a component that wraps its input in a <label> for convenience and a separate developer, unaware of the wrapping, adds a second <label for> pointing at the same input for what they think is a missing label. Both are valid HTML individually; the combination is the bug.
Does this rule apply to aria-label plus a visible label element too?
Not in the same way: aria-label always wins over a <label> element for the accessible name, so a field with both technically has one effective name, not two competing ones. This rule specifically targets multiple <label> elements, which the accessible-name algorithm concatenates rather than picks between.
Does removing one of the two labels ever lose information for sighted users?
It shouldn't, if the fix is done correctly. Read both labels' text before deleting either one; sometimes one says something like "Required" that belongs in the remaining label's text or in a separate visible note, not simply discarded.
Is this the same bug as the field having a label and a placeholder?
No, that is a different and much more common pattern. A label plus a placeholder is fine and often good practice: the placeholder supplements the label with a format hint. This rule is specifically about two or more <label> elements, not a label paired with a placeholder attribute.
Does axe-core catch a duplicate aria-labelledby reference the same way?
No, that's a separate scope. This check only counts <label> elements associated with a field. A field referencing the same id twice in aria-labelledby, or referencing conflicting ids, is a different malformed-attribute problem this rule does not evaluate.