Home / Knowledge Base / Why ID Attributes Must Be Unique

Why ID Attributes Must Be Unique

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> elements
  • aria-labelledby
  • aria-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-labelledby
  • aria-describedby
  • aria-controls
  • aria-owns
  • aria-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:

  1. Reads the string token email-label
  2. Searches the DOM for an element with id="email-label"
  3. Uses that element’s text content during accessible name computation
  4. 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 id value 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.

Want to test against all WCAG success criteria?

Stay compliant. Avoid fines. WebYes reviews your entire website so you don't have to worry.

Sign Up for Free Now