# Duplicate ID “X”.

> Canonical HTML version: https://rocketvalidator.com/html-validation/duplicate-id-x
> Attribution: Rocket Validator (https://rocketvalidator.com)
> License: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)

The `id` attribute serves as a unique identifier for a single element in the DOM. The HTML specification explicitly requires that `id` values be unique across the entire document. When you reuse an `id`, you violate this contract, and the consequences can be subtle but far-reaching.

**JavaScript behavior becomes unpredictable.** Methods like `document.getElementById()` will only return the first element with a given `id`, silently ignoring any duplicates. This can cause scripts to target the wrong element or fail to interact with elements you expect them to reach.

**CSS selectors may not apply as intended.** While most browsers will style all elements with a duplicated `id`, this behavior is not guaranteed by the specification and can lead to inconsistencies across browsers.

**Accessibility is compromised.** Screen readers and other assistive technologies rely on unique IDs to associate labels with form controls (via `for`/`id` pairing), link `aria-describedby` or `aria-labelledby` references to specific elements, and navigate fragment identifiers (anchor links). Duplicate IDs break these associations, potentially making content confusing or unusable for people relying on assistive technology.

**Fragment navigation breaks.** When a URL contains a hash like `#section-intro`, the browser scrolls to the element with that `id`. If multiple elements share the same `id`, only the first one will be targeted, which may not be the intended destination.

Common causes of duplicate IDs include copy-pasting HTML blocks without updating the `id` values, dynamically generating content in a loop without appending a unique suffix, and reusing template partials that contain hardcoded `id` attributes.

To fix this issue, audit your document for repeated `id` values. If multiple elements need the same identifier for styling purposes, use the `class` attribute instead. If the `id` is needed for JavaScript or ARIA references, make each value unique — for example, by appending a number or descriptive suffix.

## Examples

### ❌ Duplicate IDs on multiple elements

```html
<div id="card">
  <h2>First Card</h2>
</div>
<div id="card">
  <h2>Second Card</h2>
</div>
```

Both `<div>` elements share `id="card"`, which triggers the validation error.

### ✅ Use unique IDs

```html
<div id="card-1">
  <h2>First Card</h2>
</div>
<div id="card-2">
  <h2>Second Card</h2>
</div>
```

### ✅ Use `class` instead when you don't need unique identification

```html
<div class="card">
  <h2>First Card</h2>
</div>
<div class="card">
  <h2>Second Card</h2>
</div>
```

### ❌ Duplicate IDs break label associations

```html
<label for="email">Work Email</label>
<input type="email" id="email" name="work_email">

<label for="email">Personal Email</label>
<input type="email" id="email" name="personal_email">
```

Both inputs share `id="email"`, so the second `<label>` will incorrectly point to the first input. A screen reader user clicking "Personal Email" would be focused on the wrong field.

### ✅ Unique IDs for each label–input pair

```html
<label for="work-email">Work Email</label>
<input type="email" id="work-email" name="work_email">

<label for="personal-email">Personal Email</label>
<input type="email" id="personal-email" name="personal_email">
```

### ❌ Duplicate IDs in dynamically repeated content

This often happens when generating HTML in a loop or reusing a template:

```html
<section id="product">
  <h2>Widget A</h2>
</section>
<section id="product">
  <h2>Widget B</h2>
</section>
<section id="product">
  <h2>Widget C</h2>
</section>
```

### ✅ Append a unique suffix

```html
<section id="product-1">
  <h2>Widget A</h2>
</section>
<section id="product-2">
  <h2>Widget B</h2>
</section>
<section id="product-3">
  <h2>Widget C</h2>
</section>
```

If no element actually needs to be uniquely identified, remove the `id` entirely and use a `class` or a data attribute instead.
