Skip to content
easeweb
Search topics

Duplicate ids that point labels at the wrong field

A newsletter form shown in a page section and again in the footer repeats its ids, so the footer's label names, and focuses, the first copy's field.

WCAG 2.2
SC 1.3.1ASC 4.1.2A
Required by
Section 508 · EN 301 549 (EU)
Broken <input id="email" name="email" type="email">
The accessibility problem illustrated: No vision:What is this field for?
01

The problem

Screen reader users reach the footer's email field and hear no label, and a click on that label sends the cursor back up the page to the other form.

02

Try it

Scroll to the footer and click the word “Email”, then Tab into each email field.

Where does the click put the cursor? The panel shows what a screen reader says on each field.

Broken Can you fix this?

BrokenThe same form, with the same ids, in two places

Loose-leaf teas, blended in small batches

This month’s teas

  • Morning Assam $14
  • Smoked Lapsang $16
  • Mint and Nettle $12

Every tea ships in a resealable tin, and every order over $40 ships free.

  • Delivery
  • Returns
  • Contact

Screen reader says:

(Tab to an email field)

A recreated demo. The broken version is intentionally inaccessible.

03

The fix

Give each copy its own ids, or put fields in their labels.

Before
BrokenThe same form, with the same ids, in two places
<section class="signup">  <h2>Join the newsletter</h2>  <form class="signup-form" action="/subscribe" method="post">    <label for="email">Email</label>    <input id="email" name="email" type="email" autocomplete="email">    <button>Sign up</button>  </form></section>…<footer>  …  <form class="signup-form" action="/subscribe" method="post">    <label for="email">Email</label>    <input id="email" name="email" type="email" autocomplete="email">    <button>Sign up</button>  </form></footer>
What is wrong3 points
  • Two fields have id="email", so both labels go to the first one, in the band.
  • The footer's field has no label. A screen reader reads it as "edit text", and the band's field as "Email Email".
  • Clicking "Email" in the footer puts the cursor in the band's field, and the page scrolls up to it.
After

An id for each copy

<section class="signup">  <h2>Join the newsletter</h2>  <form class="signup-form" action="/subscribe" method="post">    <label for="email-signup">Email</label>    <input id="email-signup" name="email" type="email" autocomplete="email">    <button>Sign up</button>  </form></section>…<footer>  …  <form class="signup-form" action="/subscribe" method="post">    <label for="email-footer">Email</label>    <input id="email-footer" name="email" type="email" autocomplete="email">    <button>Sign up</button>  </form></footer>
How it is fixed3 steps
  1. Give the partial a value for each place it is included, such as signup and footer, and add it to every id the partial writes. Each field now has an id of its own.
  2. Point each label's for at the id in its own copy. A screen reader reads each field as "Email", and a click on either label puts the cursor in the field under it.
  3. Leave name="email" as it is. The name is what the server receives, and it may repeat; only ids must not.

This fixes the Before and passes 1.3.1 and 4.1.2. In a component framework, let the framework make the id rather than passing a word in: useId() in React and Vue, $props.id() in Svelte, or section.id for a section added through a Shopify theme's JSON templates (a static section rendered twice keeps its file name as its id). In a list, build the id from something unique to each item, such as its product id or its place in the list.

04

Verify the fix

4 checks.

Test with: Screen reader, Mouse

0 of 4 checked

Record the OS, browser and assistive-technology versions, the build, the date, and the actual result of each step. Repeat whenever a shared component is used in a new place.

Limits

This guide covers ids repeated by a component shown more than once, and what that does to labels. It doesn't cover two different elements that happen to be given the same id by hand, which is fixed by renaming one of them, or a reference to an id that is missing. Whether a repeated form also needs a different visible label in each place, such as "Email for the newsletter", is covered in vague form labels that don't say what to enter. Test the complete journey with your target assistive technology.

This is a recreated teaching example, not a finding about a named client. The code is a starting pattern: test it in your own product. No completed assistive-technology test is claimed here.

EaseWeb service

Fixed it? Keep it from coming back.

I turn guides like this one into rules your coding agents follow and checks your CI runs. Then I retest by hand with a keyboard and screen readers, periodically.

See the service