What are the ARIA roles & accessible names for HTML Elements?

testing-library/jsdom and testing-library/react expect you to find elements on your page using two things:

  1. An ARIA role
  2. An ARIA accessible name, which can and should be a human-readable piece of text such as Your Name, not an html id like your-name.

This pushes you to use ARIA. But it is said that no ARIA is better than bad ARIA, and in any case it's all very confusing unless you learn a minimum about how HTML Elements get their roles and accessible names.

A Passing Test

Copy and paste this into a react project to see the role and accessible names for a small form. (See testing-library's intro example for how to do it in vanilla html)


import React from 'react';
import {fireEvent, render, screen} from '@testing-library/react';

test('Example role and accessible names', ()=>{

  render(<form data-testid='form1'>
    <fieldset>
      <legend>Form Alpha</legend>
      <label>Search : <input type='search' value="something" /></label>
      <label><input type='checkbox' /> In Stock Only</label>
      <button>The Go Button</button>
    </fieldset>
  </form>)

  const fieldSet= screen.getByRole('group',{name:"Form Alpha"})
  expect(fieldSet).toBeVisible()

  const searchBox=screen.getByRole('searchbox', {name:/Search/i})
  expect(searchBox).toHaveValue('something')

  const checkBox=screen.getByRole('checkbox', {name:/in stock only/i})
  expect(checkBox).not.toBeChecked()
  fireEvent.click(checkBox)
  expect(checkBox).toBeChecked()

  const form=screen.getByTestId('form1')
  expect(form).toBeVisible()
})

Some of this you could have guessed and some of it you couldn't. Here is my take on the minimum you want to know to to take out most of the guesswork.

What Role and what Accessible Name do my HTML elements have?

HTML element roles

You can get a quick idea of roles just by looking at some of the defined ARIA roles:

  • article, banner, button, cell, checkbox, columnheader, combobox, command, comment, complementary, composite, contentinfo, definition, dialog, document, figure, form, generic, grid, gridcell, group, heading, img, input, landmark, link, list, listbox, listitem, log, main, mark, marquee, math, menu, menubar, menuitem, menuitemcheckbox, menuitemradio, meter, navigation, option, presentation, progressbar, radio, radiogroup, range, region, roletype, row, rowgroup, rowheader, scrollbar, search, searchbox, section, sectionhead, select, separator, slider, spinbutton, status, structure, suggestion, switch, tab, table, tablist, tabpanel, term, textbox, timer, toolbar, tooltip, tree, treegrid, treeitem, widget, window

Most of them roughly split into document structure & landmark roles vs widget roles, and you can probably guess a lot of which html elements implicitly have which roles by default, but some you would guess wrong.
Here is a table of the implicit ARIA role given by default to some commonly used html elements, along with the permitted overrides.

Implicit ARIA Roles for some common HTML elements

HTML Element Implicit ARIA Role Permissible explicit Roles
nav navigation none
article article. document, main, presentation &c.
a href="..." link button,checkbox,menuitem &c.
a without href none any
button button tab, checkbox, combobox, link, menuitem, &c
form form but only if it has an accessible name search, none or presentation
fieldset group radiogroup, presentation, none
img alt="..." img button, checkbox, link, menuitem, option, tab &c
img alt="" presentation presentation, none
input[type=button] button checkbox, combobox, link, &c
input[type=checkbox] checkbox button with aria-pressed, &c
input[type=image] button link, menuitem, radio, switch &c
input[type=number] spinbutton
input[type=radio] radio menuitemradio
input[type=range] slider
input[type=reset] button
input[type=submit] button
input[type=search] with no list attribute searchbox none
input[type=search] with list attribute combobox none
input[type=email] with no list attribute textbox none
input[type=email] with list attribute combobox none
input[type=tel] with no list attribute textbox none
input[type=tel] with list attribute combobox none
input[type=text] with no list attribute textbox combobox, searchbox, &c
input[type=text] with list attribute combobox none
input[type=url] with no list attribute textbox none
input[type=url] with list attribute combobox none
ul,ol list directory, group, listbox, menu, menubar, &c
label,legend none none
main main none
menu list directory, group, listbox, menu, menubar, &c
optgroup group none
option option none
select with multiple attribute & no size greater than 1 combobox menu
select otherwise listbox none
textbox textbox none
table table any
td cell, if a descendant of a table any
th columnheader or rowheader any

You can see some patterns:

  • Many elements such as main, article, option, textbox have a fixed semantic meaning which is pretty much the same as their role. They can only have that fixed role and it can't be overridden.
  • Some elements have no implicit Aria role but can be given any explicit role. These elements include div,span,code,blockquote,most of text elements such as em,strong, &c.
  • Invisible elements such as style and script have no aria role and are not permitted an explicit role either.
  • Label and legend are in a sense special elements whose aria job is to label some other element with an accessible name. They can't be given any other role.
  • Some element roles including a,img,select (and of course input) depend on how their attributes are set.
  • See the HTML element reference pages to find the full list of html elements and the full list of permitted explicit roles for those that aren't in the above table.

The table mentions what explicit roles can be given. An explicit role is given to an HTML element by giving it a role="rolename" attribute. But the advice is to only do this when you have to. Work with the native HTML roles.

HTML Element Accessible Names

An accessible name can and should be a human-readable piece of text such as 'Your Name', not an html id like your-name.

To understand what the accessible name of a component is, you must understand the accessible name computation. Here are, roughly, the first 3 steps of the accessible name computation for HTML. This is enough to get you off the ground and calculate most of your accessible names.

The Accessible Name Computation for HTML Elements

  1. The aria-labelledby property is used if present.
  2. If the name is still empty, the aria-label property is used if present.
  3. If the name is still empty, then the 3rd step depends on the element and is described in the w3.org Accessible Name Computation Section By HTML Element. Here is a summary table:
HTML Element Accessible Name Calculation if the element has no aria-label or aria-labelledby
<input type="text">, <input type="password">, <input type="number">, <input type="search">, <input type="tel">, <input type="email">, <input type="url"> and <textarea> Use the associated label element or elements accessible name(s) - if more than one label is associated; concatenate by DOM order, delimited by spaces.
If the accessible name is still empty, then: use the control's title attribute.
Use the control's placeholder value.
<input type="button">, <input type="submit"> and <input type="reset"> Accessible Name Computation Use the associated label element(s) accessible name(s) - if more than one label is associated; concatenate by DOM order, delimited by spaces.
Use the value attribute.
For input type=submit and type=reset: if the prior steps do not yield a usable text string, and the value attribute is unspecified use the implementation defined string respective to the input type.
Otherwise, if the control still has no accessible name use title attribute.
<input type="image"> Accessible Name Computation Use the associated label element(s) accessible name(s) - if more than one label is associated; concatenate by DOM order, delimited by spaces.
Use alt attribute if present and its value is not the empty string.
Use title attribute if present and its value is not the empty string.
Otherwise if the previous steps do not yield a usable text string, use the implementation defined string respective to the input type (an input in the image state represents a submit button). For instance, a localized string of the word "submit" or the words "Submit Query".
<button> Use the associated label element(s) accessible name(s) - if more than one label is associated; concatenate by DOM order, delimited by spaces.
Use the button element subtree.
Use title attribute.
<fieldset> If the accessible name is still empty, then: if the fieldset element has a child that is a legend element, then use the subtree of the first such element.
If the accessible name is still empty, then:, if the fieldset element has a title attribute, then use that attribute.
Otherwise, there is no accessible name.
<output> Use the associated label element or elements accessible name(s) - if more than one label is associated; concatenate by DOM order, delimited by spaces.
Use title attribute.
Other Form Elements Use label element.
Use title attribute.
<summary> If the first summary element, which is a direct child of the details element, has an aria-label or an aria-labelledby attribute the accessible name is to be calculated using the algorithm defined in Accessible Name and Description: Computation and API Mappings.
Use summary element subtree.
Use title attribute.
If there is no summary element as a direct child of the details element, the user agent should provide one with a subtree containing a localized string of the word "details".
If there is a summary element as a direct child of the details element, but none of the above yield a usable text string, there is no accessible name.
<figure> If the accessible name is still empty, then: if the figure element has a child that is a figcaption element, then use the subtree of the first such element.
If the accessible name is still empty, then: if the figure element has a title attribute, then use that attribute.
<img> Use alt attribute, even if its value is the empty string.
NOTE
An img with an alt attribute whose value is the empty string is mapped to the presentation role. It has no accessible name.
Otherwise, if there is no alt attribute use the title attribute.
<table> if the table element has a child that is a caption element, then use the subtree of the first such element.
if the table element has a title attribute, then use that attribute.
tr, td, th Use the title attribute.
<a> Use a element subtree.
Use the title attribute.
<area> Use area element's alt attribute.
Use the title attribute.
<iframe> Use the title attribute.
NOTE
The document referenced by the src of the iframe element gets its name from that document's title element, like any other document
Section and Grouping p, hr, pre, blockquote, ol, ul, li, dl, dt, dd, figure, figcaption, div, main and body, article, section, nav, aside, h1, h2, h3, h4, h5, h6, header, footer, address Use the title attribute.
Text-level Elements: abbr, b, bdi, bdo, br, cite, code, dfn, em, i, kbd, mark, q, rp, rt, ruby, s, samp, small, strong, sub and sup, time, u, var, wbr Use the title attribute.

The third step is the thing to focus on. If you learn what the accessible name is for your most commonly used html elements then you have less need of the aria-label or aria-labelledby attributes. You can see that elements fallback to the title attribute, but you are recommended to avoid this. If this table does not provide a better place to put your accessible name, then use aria-label="my accessible name" or aria-labelledby="id-of-label-element".

I said that this is roughly the computation. Rather than learning this table, you could learn which roles permit name from content, and that would get you to almost the same result.

Read more, with examples: https://www.w3.org/WAI/ARIA/apg/practices/names-and-descriptions/#cardinalrulesofnaming

Overriding the default name

In almost all cases you can override the default naming scheme by given an element either an aria-label="This is my name" attribute, or an aria-labelledby="id-of-a-labelling-element-with-text-content"

Parting comments

Returning to my original example, you can see that aria is opiniated. The <form> element has no built-in accessible name, whereas the input elements do. This perhaps reflects the fact that a user is much more aware of the interactive elements themselves, not the logical structure they are held in. You can also see that although many aria roles and naming rules look like what you'd expect, the thinking behind ARIA isn't identical to the thinking behind html.

Learning to do it well

A starting point for learning how to create good accessible sites is https://www.w3.org/WAI/ARIA/apg/

The Panama Pepers: a longtail SEO example

A Flemish friend commented recently on facebook that after all the news items about the 'Panama pepers' there were still no hits for it in search engines. (For those of you not previously acquainted with the Flemish talent for multi-lingual puns, I should explain that 'peper' in Dutch as pronounced as the English 'paper' but means pepper. He went on to mention a secret recipe for Norwegian salmon with Panamanian peppers).

And it was true! There were no hits on all the interwebs for Panama pepers.

Which brings us to the subject of longtail SEO. By writing pages on specific, not-widely-popular terms, websites attract to their site the small number of visitors who are interested in the topics to which they think searching those terms will lead them. Except: 'small', when your potential audience is The World may mean hundreds of thousands of visitors. Not so small after all.

Although Pepers is not an english word, by writing an article on the subject, and especially by discussing the Panama papers & Panama pepers (not to mention associated recipes), I thereby expect to rise to search engine page 1, if not hit #1, for the term.
We'll see how it goes...

Update after 4 months

www.google.be/#q=panama+pepers now produces thousands of hits. This page made it to the first page, but only just. Clearly I need still lack a recipe or two for Panamanian peppers.

De Panama Pepers: een voorbeeld van SEO longtail.

Een Vlaamse vriend merkte onlangs op facebook dat na al het nieuws over de 'Panama pepers' waren er nog geen treffers voor die termijn in de zoekmachines. (Voor degenen onder u die niet eerder kennisgemaakt hebben met de Vlaamse talent voor multi-lingual woordspelingen, moet je weten dat 'peper' wordt in het Nederlands net zo uitgesproken als het Engels 'papers'. Hij merkte verder een geheim recept voor Noorse zalm met Panamese pepers).

En het was ook zo! Er waren geen hits op de interwebs voor 'Panama pepers'

Wat brengt ons op ons onderwerp: longtail SEO. Door het schrijven van pagina's over specifieke, niet-alom-populaire termen, trekken websites het kleine aantal bezoekers aan die interesse hebben voor de betrokkene onderwerpen. Alhoewel: 'klein', wanneer uw potentiële publiek de wereld is, kan honderdduizenden bezoekers betekenen. Niet zo klein, dus.

Hoewel 'Pepers' geen Engels is, wordt door het schrijven van een artikel over het onderwerp, en in het bijzonder door het bespreken van de Panama papieren & Panama pepers (en de bijbehorende recepten), verwacht ik uiteindelijk eerste plaats te nemen in zoekmachine rankings.

We zien wel hoe het gaat ...