# Form elements must have labels. Use <label>, aria-label, or aria-labelledby.

> Canonical HTML version: https://rocketvalidator.com/accessibility-validation/accesslint/0.16/labels-and-names/form-label
> Attribution: Rocket Validator (https://rocketvalidator.com)
> License: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)

Every form field needs an accessible name so that assistive technologies can announce what the field is for. When a screen reader encounters an `<input>`, `<select>`, `<textarea>`, or a custom control with a role like `checkbox`, `combobox`, `listbox`, `radio`, `searchbox`, `slider`, `spinbutton`, `switch`, or `textbox`, it reads the accessible name aloud. Without one, users who rely on screen readers hear something generic like "edit text" or "checkbox" with no indication of what information the field expects. Keyboard-only users and voice control users are also affected, since voice control software often uses visible labels to target form fields by name.

This rule maps to WCAG 2.0 success criterion [4.1.2 Name, Role, Value](https://www.w3.org/WAI/WCAG21/Understanding/name-role-value.html) at Level A. That success criterion requires every user interface component to have a name that can be programmatically determined. A form field that lacks an accessible name fails this requirement outright.

## How to fix it

There are several ways to give a form field an accessible name. Choose the method that fits the situation:

**Use a `<label>` element.** This is the most common and preferred approach. Either wrap the input inside the `<label>`, or use the `for` attribute on the `<label>` to point to the input's `id`. This method creates both a visible label and a programmatic association, which also gives sighted users a larger click target.

**Use `aria-label`.** When a visible label is not part of the design (for example, a search field next to a search button), add an `aria-label` attribute directly on the form field. The value is a text string that screen readers will announce. Keep in mind that `aria-label` produces no visible text, so it should only be used when the field's purpose is already visually clear from surrounding context.

**Use `aria-labelledby`.** When the label text already exists somewhere on the page but is not a `<label>` element, use `aria-labelledby` on the form field and set its value to the `id` of the element containing the label text.

A common mistake is relying on `placeholder` text as the only label. While some browsers do expose `placeholder` as the accessible name when nothing else is available, placeholder text disappears as soon as the user starts typing. This makes the field harder to use for people with cognitive disabilities and for anyone who needs to verify what they entered. Always provide a persistent label through one of the methods above.

Labels should describe the information being requested, not the type of field. "Email address" or "Phone number" are good labels. "Text field" or "Input" are not.

This rule also applies to disabled form fields. Many assistive technologies include disabled fields when listing all form controls on a page, so those fields still need accessible names.

## Examples

### Missing label on an input

This input has no `<label>`, no `aria-label`, and no `aria-labelledby`. A screen reader will not be able to announce what the field is for.

```html
<div>Email address</div>
<input type="email" />
```

### Placeholder used as the only label

The placeholder text disappears when the user types, leaving no persistent indication of the field's purpose.

```html
<input type="text" placeholder="First name" />
```

### Fixed with a `<label>` wrapping the input

```html
<label>
  Email address
  <input type="email" />
</label>
```

### Fixed with a `<label>` using the `for` attribute

```html
<label for="email">Email address</label>
<input type="email" id="email" />
```

### Fixed with `aria-label`

```html
<input type="search" aria-label="Search" />
<button type="submit">Search</button>
```

### Fixed with `aria-labelledby`

```html
<div id="comment-label">Your comment</div>
<textarea aria-labelledby="comment-label"></textarea>
```

### Select element with a proper label

```html
<label for="country">Country</label>
<select id="country">
  <option>Canada</option>
  <option>Mexico</option>
  <option>United States</option>
</select>
```

### Checkbox with a label

```html
<label>
  <input type="checkbox" />
  I agree to the terms of service
</label>
```
