In HTML, an id is a document-wide identifier. Per the HTML Living Standard, an ID value must be unique within the document. When IDs are reused, especially in ARIA attributes or form labels, browsers cannot reliably resolve relationships between elements. As a result, assistive technologies may compute incorrect names, miss associations, or expose incomplete semantics.
This is invalid HTML, and when it affects accessible names or relationships, it leads to WCAG 2.2 failures under SC 4.1.2.
WCAG Success Criterion
Success Criterion: Name, Role, Value (4.1.2) – Level A
User interface components must have a name and role that can be programmatically determined, and states, properties, and values that can be programmatically set and announced to assistive technologies.
ARIA attributes and form labels often rely on ID references to compute a component’s accessible name or description. If those IDs are duplicated, the browser cannot programmatically determine the correct relationship.
Foundational Concepts
What Is an ID?
An id is a unique token used to identify exactly one element in the DOM. It allows other parts of the document, ARIA attributes, labels, and scripts, to refer to that element unambiguously.
If an ID appears more than once, it no longer uniquely identifies anything.
What Is an Accessible Name?
An accessible name is the text that assistive technologies announce to identify a control, such as:
- “Email address”
- “Submit”
- “Shipping information”
Accessible names are computed, not guessed.
They are derived from sources such as:
<label>elementsaria-labelledbyaria-label- Native element text (depending on role)
What Is the Accessibility Tree?
Browsers do not expose raw HTML to screen readers.
Instead, they build an accessibility tree, derived from:
- The DOM
- Native HTML semantics
- ARIA roles, states, and properties
If relationships in the DOM are ambiguous or invalid (for example, due to duplicate IDs), the accessibility tree may be incomplete or incorrect.
What Is a Programmatic Association?
A programmatic association is a relationship that software, not sight, can determine.
Examples:
- A
<label>associated with an<input> - A description referenced by
aria-describedby - A name computed via
aria-labelledby
These associations depend on ID references resolving correctly.
What This Rule Checks
This rule ensures that:
- Every ID referenced by ARIA attributes is unique
- Every ID referenced by
<label for="">is unique - ARIA relationships resolve to exactly one element per ID
Affected attributes include (but are not limited to):
aria-labelledbyaria-describedbyaria-controlsaria-ownsaria-activedescendant- headers (for complex tables)
What an ID Reference Actually Does
ARIA attributes contain string tokens, not element references.
Example:
<input aria-labelledby="email-label">
The browser performs these steps:
- Reads the string token email-label
- Searches the DOM for an element with
id="email-label" - Uses that element’s text content during accessible name computation
- Exposes the result in the accessibility tree
If more than one element shares the same ID:
- The mapping becomes ambiguous
- Name computation may fail or behave inconsistently
- Results vary across browser and assistive technology combinations
Screen readers do not guess. They rely on resolved DOM relationships.
Correct Markup Examples
Unique label association (recommended)
<label for="email">Email address</label>
<input id="email" type="email">
The label and input are unambiguously associated.
Unique ARIA description
<p id="password-hint">Must be at least 8 characters.</p>
<input
type="password"
aria-describedby="password-hint">
The ID resolves to a single element used as the description.
Multiple IDs in aria-labelledby (valid pattern)
<span id="first-name-label">First name</span>
<span id="required-indicator">(required)</span>
<input
aria-labelledby="first-name-label required-indicator">
Notes:
- Space-separated ID lists are allowed
- Each ID must be unique
- All referenced elements contribute to the accessible name
Incorrect Markup Examples
Duplicate IDs in form labels
<label for="email">Email</label>
<input id="email" type="email">
<label for="email">Confirm email</label>
<input id="email" type="email">
Result:
- Invalid HTML
- Accessible name computation becomes unreliable
- Screen reader behavior is undefined and inconsistent
Duplicate IDs in ARIA references
<p id="hint">Required field</p>
<p id="hint">Must not be empty</p>
<input aria-describedby="hint">
The browser cannot reliably determine which description applies.
Reused IDs in repeated components
<div id="card">...</div>
<div id="card">...</div>
Common in copy-pasted markup or improperly scoped components.
Why This Matters
ARIA and label relationships are resolved through ID-based DOM lookups.
Duplicate IDs create ambiguous mappings that browsers and assistive technologies cannot interpret consistently.
Consequences include:
- Incorrect or missing accessible names
- Broken descriptions
- Controls exposed without context
- Inconsistent behaviour across NVDA, JAWS, VoiceOver, and TalkBack
Behaviour is not reliably predictable once IDs are duplicated.
HTML Validity vs WCAG Compliance (2025 Nuance)
- Duplicate IDs are a parsing error under HTML
- WCAG 2.2 removed SC 4.1.1 (Parsing)
- Duplicate IDs are not automatically a WCAG failure
However, Duplicate IDs frequently cause WCAG 4.1.2 failures when they interfere with accessible name, role, or relationship computation. This distinction is critical in modern audits.
Common Causes of Failure
- Copy-pasted components with static IDs
- Repeated React/Vue components without scoped IDs
- Server-side rendering mismatches
- Auto-generated IDs are not guaranteed to be unique
- Using IDs for styling instead of classes
Framework & Component Warnings
In component-based frameworks:
- Do not reuse static IDs inside repeated components
- Generate IDs dynamically or scope them per instance
- Be cautious with hydration mismatches that duplicate markup
This is a common source of accessibility defects in modern applications.
How This Is Tested
Audits typically include:
- Automated detection of duplicate IDs (axe, Lighthouse, WAVE)
- Manual inspection in browser DevTools → Accessibility panel
- Verifying computed accessible names
- Testing with screen readers (NVDA, JAWS, VoiceOver)
Automated tools can detect duplicates, but manual testing confirms impact.
How to Fix the Problem
- Ensure every
idvalue is unique within the document - Rename duplicated IDs
- Use classes for styling
- Dynamically generate IDs in repeated components
- Verify ARIA references resolve to exactly one element
Wrapping Up
IDs are the mechanism by which browsers resolve ARIA and label relationships in the DOM.
When IDs are duplicated, those relationships become ambiguous and cannot be reliably exposed in the accessibility tree.
While WCAG 2.2 no longer enforces HTML parsing rules directly, duplicate IDs remain a frequent root cause of Name, Role, Value failures. One ID must identify one—and only one—element. Anything else undermines programmatic accessibility.