Skip to main content

About This Accessibility Rule

When you use ARIA roles to create custom input controls instead of native HTML elements, the browser no longer automatically associates a label with the control. Native <input>, <select>, and <textarea> elements support the <label> element through implicit wrapping or explicit for/id pairing, but custom <div> or <span> elements with ARIA roles do not. This means you must supply an accessible name through ARIA-specific mechanisms.

This rule applies to elements with any of the following ARIA input roles:

  • combobox
  • listbox
  • searchbox
  • slider
  • spinbutton
  • textbox

Who is affected

Without an accessible name, users who rely on screen readers (including blind and deafblind users) hear only the role of the element — for example, “textbox” — with no indication of what information to enter. Users with mobility impairments who navigate via voice control also depend on accessible names to target specific controls by speaking their labels. This creates a serious barrier to interaction.

Related WCAG success criteria

This rule maps to WCAG 2.0, 2.1, and 2.2 Success Criterion 4.1.2: Name, Role, Value (Level A). This criterion requires that all user interface components have a name that can be programmatically determined by assistive technologies. It is a Level A requirement, meaning it represents the minimum baseline of accessibility.

How to fix the problem

Because <label> elements do not work reliably with non-native elements like <div> or <span>, you need to use one of these approaches:

  1. aria-label — Add a concise, descriptive label directly on the element.
  2. aria-labelledby — Point to the id of one or more visible elements that serve as the label.
  3. title — Use the title attribute as a last resort (it is less discoverable for sighted users).

Make sure the accessible name you provide is not empty or whitespace-only, and that any id referenced by aria-labelledby actually exists in the DOM.

Common mistakes

  • Setting aria-label to an empty or whitespace-only string (e.g., aria-label=" ").
  • Using aria-labelledby with an id that doesn’t exist on the page.
  • Wrapping a custom ARIA widget in a <label> element, which does not provide a programmatic name for non-native elements in most browser/screen reader combinations.
  • Using <label for="id"> to point to a <div> — the for attribute only works with native labelable elements like <input>, <select>, and <textarea>.

Examples

Incorrect: no accessible name on a combobox

The <div> has a combobox role but no label of any kind.

<div role="combobox">England</div>

Incorrect: aria-label is only whitespace

An empty or whitespace-only aria-label does not count as an accessible name.

<div aria-label=" " role="combobox">England</div>

Incorrect: aria-labelledby references a non-existent id

The referenced id must exist in the document; otherwise the accessible name resolves to empty.

<div role="listbox" aria-labelledby="color-label">
  <div role="option">Orange</div>
</div>
<!-- No element with id="color-label" exists -->

Incorrect: <label> wrapping a non-native element

Implicit label association does not work for <div> elements with ARIA roles.

<label>
  First name
  <div role="textbox"></div>
</label>

Incorrect: explicit <label for> targeting a non-native element

The for attribute only creates a programmatic association with native labelable elements.

<label for="name-field">First name</label>
<div role="textbox" id="name-field"></div>

Correct: aria-label on a combobox

<div role="combobox" aria-label="Country">England</div>

Correct: aria-labelledby pointing to a visible label

<p id="color-label">Select a color:</p>
<div role="listbox" aria-labelledby="color-label">
  <div role="option">Orange</div>
</div>

Correct: aria-labelledby on a searchbox

<p id="search-label">Search currency pairs:</p>
<div role="searchbox"
  contenteditable="true"
  aria-labelledby="search-label"></div>

Correct: aria-label on a slider

<div role="slider"
  aria-label="Choose a value"
  aria-valuemin="1"
  aria-valuemax="7"
  aria-valuenow="2"
  tabindex="0"></div>

Correct: aria-label on a spinbutton

<div role="spinbutton"
  aria-label="Enter quantity"
  aria-valuemin="0"
  aria-valuemax="10"
  aria-valuenow="8"
  tabindex="0"></div>

Correct: aria-labelledby on a textbox

<p id="name-label">First name</p>
<div role="textbox"
  contenteditable="true"
  aria-labelledby="name-label"></div>

When possible, prefer native HTML form controls (<input>, <select>, <textarea>) because they have built-in label support and keyboard behavior. Use custom ARIA input roles only when native elements cannot meet your design requirements, and always ensure those custom controls have an accessible name.

Help us improve our guides

Was this guide helpful?

Detect accessibility issues automatically

Rocket Validator scans thousands of pages with Axe Core and the W3C Validator, finding accessibility issues across your entire site.

Ready to validate your sites?
Start your free trial today.