How to fix: Duplicate element IDs
Every id attribute on a page must be unique: if the same id value appears on more than one element, rename the duplicates so each id is used only once.
What it is
An id is meant to be a unique handle for a single element. The HTML specification requires id values to be unique within a document, and a great deal of accessibility plumbing depends on that guarantee. WCAG Success Criterion 4.1.1 Parsing (in WCAG 2.1) treats duplicate IDs as a markup defect, because when two elements share an id, anything that points to that id becomes ambiguous: the browser and assistive technology can only resolve it to one element, usually the first.
Duplicates creep in easily. A reusable component (a card, a form field, a modal) gets rendered several times on the same page, each copy carrying the same hard-coded id. A template fragment is pasted twice. Two developers independently pick id="title". Visually nothing looks wrong, which is exactly why the problem goes unnoticed until something that relies on the id silently misbehaves.
The consequences are concrete. A <label for="x"> associates with only the first element that has id="x", so the second copy's field is effectively unlabeled. ARIA references like aria-labelledby, aria-describedby, and aria-controls resolve to the first match, so a control can announce the wrong name or description. In-page anchors (href="#x") and scripts that call getElementById jump to or operate on the wrong element. The fix is simply to make each id unique.
Who it affects & why it matters
Screen reader users are affected whenever a duplicated id sits behind a label or an ARIA relationship. If a field's <label for> or aria-labelledby resolves to the wrong (first) element, the user hears the wrong name or no name at all, which is especially damaging on forms where guessing the wrong field means a failed submission.
Keyboard and all users are affected when duplicated IDs break in-page skip links and anchor navigation, sending focus to the wrong spot, and scripts that target an element by id can act on the wrong one, producing erratic behavior that is hard to trace. Because the page looks fine, these failures are easy to ship and hard to debug, hurting reliability for everyone.
Duplicate IDs fall under SC 4.1.1, a Level A criterion, the most basic conformance tier. They are trivial for automated tools to detect, which is exactly why they show up in audits and in the demand letters plaintiff firms send. WCAG 2.1 Level AA is the de-facto benchmark U.S. courts apply to ADA Title III claims, and it includes every Level A criterion, so a documented Level A markup failure is an obvious item to clear.
Web accessibility lawsuits keep climbing year over year and most often target businesses under $25 million in revenue, and duplicate IDs are doubly costly because they are both a flagged violation and a real source of broken labels and navigation. Renaming a handful of ids is a quick, low-risk fix that removes an easy audit finding and restores the label, ARIA, and anchor wiring that depends on uniqueness.
How to fix it
- Collect every element with an id attribute and look for any id value that appears more than once.
- For each duplicated id, decide which element keeps the original value and rename the others to something unique and descriptive.
- Update everything that points at the renamed ids: matching label for attributes, aria-labelledby / aria-describedby / aria-controls references, href="#id" anchors, and any getElementById or querySelector calls.
- For reusable components that render multiple times, generate ids dynamically (for example by appending an index or a unique key) instead of hard-coding them.
- Re-scan to confirm every id on the page is now unique.
<label for="email">Work email</label>
<input id="email" type="email">
<label for="email">Personal email</label>
<input id="email" type="email"><label for="work-email">Work email</label>
<input id="work-email" type="email">
<label for="personal-email">Personal email</label>
<input id="personal-email" type="email">How AccessKnight detects this
AccessKnight selects every element that has an id attribute and tallies how many times each id value occurs. Any id value that appears more than once is flagged, and the finding reports the duplicated value and how many times it was used, with the fix to make that id unique. Each distinct duplicated id produces its own finding. Elements with a unique id, or with no id at all, are not reported.