# Any “select” descendant of a “label” element with a “for” attribute must have an ID value that matches that “for” attribute.

> Canonical HTML version: https://rocketvalidator.com/html-validation/any-select-descendant-of-a-label-element-with-a-for-attribute-must-have-an-id-value-that-matches-that-for-attribute
> Attribution: Rocket Validator (https://rocketvalidator.com)
> License: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)

The `label` element associates a caption with a form control. There are two ways to create this association:

1. **Implicit association** — Place the form control directly inside the `label` element. No `for` or `id` attributes are needed.
2. **Explicit association** — Use the `for` attribute on the `label`, setting its value to the `id` of 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:

1. **Remove the `for` attribute** — If the `select` is already inside the `label`, implicit association handles everything. This is the simplest fix.
2. **Add or correct the `id`** — Keep the `for` attribute but ensure the `select` has a matching `id`.

## Examples

### ❌ Incorrect: `for` attribute with no matching `id`

The `for` attribute references `"age"`, but the `select` has no `id` at all:

```html
<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`:

```html
<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:

```html
<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`:

```html
<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:

```html
<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.
