# The “aria-labelledby” attribute must not be used on any “label” element that is an ancestor of a labelable element.

> Canonical HTML version: https://rocketvalidator.com/html-validation/the-aria-labelledby-attribute-must-not-be-used-on-any-label-element-that-is-an-ancestor-of-a-labelable-element
> Attribution: Rocket Validator (https://rocketvalidator.com)
> License: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)

The `aria-labelledby` attribute is not allowed on a `<label>` element when that `<label>` contains a labelable element (such as `<input>`, `<select>`, `<textarea>`, or `<button>`).

A `<label>` that wraps a form control gives that control its accessible name from the label's text. `aria-labelledby` also sets an accessible name, by pointing at other elements through their `id`. Putting it on the `<label>` names the label itself, not the control, and browsers differ on whether that referenced text replaces the label's own text when they compute the control's name. A screen reader user may hear the visible label, the referenced text, or a mix of both.

The spec avoids that ambiguity by rejecting `aria-labelledby` on a `<label>` that is an ancestor of a labelable element. A "labelable element" is any element a `<label>` can be associated with: `<input>` (except `type="hidden"`), `<select>`, `<textarea>`, `<button>`, `<meter>`, `<output>`, and `<progress>`.

If the label's visible text is enough, remove `aria-labelledby`. If the control needs a name built from other text on the page, put `aria-labelledby` on the control instead. On the control it overrides the `<label>`, so include the label's own `id` in the list to keep the visible text in the name.

## Examples

### Invalid: `aria-labelledby` on a `label` that wraps an input

```html
<h2 id="shipping-heading">Shipping address</h2>
<label aria-labelledby="shipping-heading">
  Postcode
  <input type="text" name="postcode">
</label>
```

### Fixed: remove the attribute

```html
<h2 id="shipping-heading">Shipping address</h2>
<label>
  Postcode
  <input type="text" name="postcode">
</label>
```

### Fixed: move it to the input

```html
<h2 id="shipping-heading">Shipping address</h2>
<label id="postcode-label" for="postcode">Postcode</label>
<input type="text" id="postcode" name="postcode" aria-labelledby="shipping-heading postcode-label">
```
