Skip to content

useControlLabel

biome.json
{
"linter": {
"rules": {
"nursery": {
"useControlLabel": "error"
}
}
}
}

Enforce that interactive control elements have an accessible label.

A control with no accessible label is announced by assistive technology as an anonymous control (e.g. just “button”), leaving its purpose unclear. A label can come from text content anywhere inside the control, aria-label, aria-labelledby, or title attribute.

This rule checks native controls whose accessible name is expected to come from their own content or attributes (button, menuitem). Elements hidden from assistive technology with aria-hidden are skipped, as are elements that already require a text alternative under a dedicated rule (e.g. area, img, checked by useAltText).

The search through the content of a control is permissive: anything whose rendered output cannot be determined statically, such as an expression, a spread, or a custom component, is assumed to provide a label.

<button />;
code-block.jsx:1:1 lint/nursery/useControlLabel ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

This control element has no accessible label.

> 1 │ <button />;
^^^^^^^^^^
2 │

Assistive technology announces it as an anonymous control, so its purpose is unclear to screen-reader users.

Add text content, or an aria-label, aria-labelledby, or title attribute.

This rule belongs to the nursery group, which means it is not yet stable and may change in the future. Visit https://biomejs.dev/linter/#nursery for more information.

<button></button>;
code-block.jsx:1:1 lint/nursery/useControlLabel ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

This control element has no accessible label.

> 1 │ <button></button>;
^^^^^^^^
2 │

Assistive technology announces it as an anonymous control, so its purpose is unclear to screen-reader users.

Add text content, or an aria-label, aria-labelledby, or title attribute.

This rule belongs to the nursery group, which means it is not yet stable and may change in the future. Visit https://biomejs.dev/linter/#nursery for more information.

An icon button whose content renders nothing announceable:

<button><i className="icon-save" /></button>;
code-block.jsx:1:1 lint/nursery/useControlLabel ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

This control element has no accessible label.

> 1 │ <button><i className=“icon-save” /></button>;
^^^^^^^^
2 │

Assistive technology announces it as an anonymous control, so its purpose is unclear to screen-reader users.

Add text content, or an aria-label, aria-labelledby, or title attribute.

This rule belongs to the nursery group, which means it is not yet stable and may change in the future. Visit https://biomejs.dev/linter/#nursery for more information.

<button>Submit</button>;
<button aria-label="Close" />;
<button><Icon /><span>Delete</span></button>;
<button><img src="save.png" alt="Save" /></button>;