About This HTML Issue
The label element associates a caption with a form control. There are two ways to create this association:
-
Implicit association — Place the form control directly inside the
labelelement. Nofororidattributes are needed. -
Explicit association — Use the
forattribute on thelabel, setting its value to theidof the associated form control.
Both methods work independently. The problem arises when you mix them incorrectly — nesting a select inside a label that has a for attribute, but the select either has no id or has an id that doesn’t match the for value. In this situation, the explicit association (via for) points to nothing or to the wrong element, while the implicit association (via nesting) still exists. This contradictory state violates the HTML specification and can cause assistive technologies like screen readers to misidentify or skip the label, reducing accessibility for users who rely on them.
The WHATWG HTML specification requires that when a for attribute is present on a label, it must reference a valid labelable element by id. If the form control is already nested inside the label, the for attribute is redundant — but if present, it still must correctly reference that control.
How to Fix
You have two options:
-
Remove the
forattribute — If theselectis already inside thelabel, implicit association handles everything. This is the simplest fix. -
Add or correct the
id— Keep theforattribute but ensure theselecthas a matchingid.
Examples
❌ Incorrect: for attribute with no matching id
The for attribute references "age", but the select has no id at all:
<label for="age">
Age
<select>
<option>Young</option>
<option>Old</option>
</select>
</label>
❌ Incorrect: for attribute with a mismatched id
The for attribute references "age", but the select has a different id:
<label for="age">
Age
<select id="age-select">
<option>Young</option>
<option>Old</option>
</select>
</label>
✅ Fix option 1: Remove the for attribute (implicit association)
Since the select is nested inside the label, implicit association is sufficient:
<label>
Age
<select>
<option>Young</option>
<option>Old</option>
</select>
</label>
✅ Fix option 2: Match the for attribute with the id (explicit association)
Keep the for attribute and give the select a matching id:
<label for="age">
Age
<select id="age">
<option>Young</option>
<option>Old</option>
</select>
</label>
✅ Fix option 3: Separate the label and select (explicit association only)
If you prefer to keep the select outside the label, explicit association with matching for and id is required:
<label for="age">Age</label>
<select id="age">
<option>Young</option>
<option>Old</option>
</select>
In most cases, option 1 (removing the for attribute) is the cleanest solution when the control is already nested. Use explicit association when the label and control are in separate parts of the DOM, such as in complex table or grid layouts.
Find issues like this automatically
Rocket Validator scans thousands of pages in seconds, detecting HTML issues across your entire site.