Practical accessibility, part 2: Name (almost) everything
When browsers and screen readers encounter an element, they use semantic markup and ARIA attributes to tell users what it is (ul
is a list) and how it’s supposed to work (role="menu"
). But they can’t say why it’s there without an accessible name.
Accessible names can be summed up as: the text that identifies this instance of an element or component. It’s the text in a link or button, a heading element associated with a widget, or a form element’s label. It’s the value given to attributes like aria-labelledby
and aria-label
when visible labels would get in the way (think: global navigation bar).
It seems like a simple concept, but like many things in web development, naming is both critical to accessibility and very easy to omit or implement badly.
Why it matters to get naming right
Permalink to 'Why it matters to get naming right'Aside from the fact that names are required to achieve the most basic level of accessibility compliance, they provide wayfinding assistance, differentiate similar widgets from each other, and inform users of assistive technology how your interface works.
Elements and components on your page that are interactive or contain meaningful content need identifying text in the markup. Screen readers rely on text to create a usable experience. Voice control users need clear text labels that match the underlying code so they can accurately move about the page.
But this doesn’t mean we should slap a name on everything. It requires some restraint. Too many names, or names applied incorrectly, and you could end up with noisy or unusable content.
Which elements need explictly set names?
Permalink to 'Which elements need explictly set names?'Essentially, the following:
- focusable, interactive elements - links, forms and form elements, custom-built widgets like accordion, carousel, tabs, etc
- non-text elements that require a text equivalent - images, icons, videos, embedded frames
- labeling elements - headings, form labels
- tables, too, via the
caption
element
Some elements should remain anonymous
Permalink to 'Some elements should remain anonymous'Generally, elements that don’t gain focus, convey meaningful content, or enable user interaction can safely remain nameless and in the background. This is true of non-specific elements that lay out the page, like <div class="column">
, or elements that are purely decorative. In fact, naming everything to that degree could be distracting to screen readers who are listening for salient content.
Do landmarks need names? Yes and no.
Permalink to 'Do landmarks need names? Yes and no.'Landmarks identify major sections of the page for screen readers and can be accessed via screen reader-specific key commands — whether their content is interactive or not. (For a refresher on landmark semantics and roles, see Part 1.)
A name is required for some landmarks, but not for others. Landmarks that are limited to one per page, like a top-level banner
, can be identified by their role alone.
I made up cheat lists to sort them out, and noted role values that confer landmark status (i.e., navigation
) and sectioning elements that have implied landmark roles (<nav>
):
Landmarks that require a name
Permalink to 'Landmarks that require a name'navigation
or<nav>
, especially when multiple exist on a pageform
or<form>
- not just a name, but a visible nameregion
, which by definition is unspecific so it needs a name to clarify its purposemain
or<main>
- not technically required, but I’ve included it here because it’s good practice to associate the H1 element with the main content in your page viaaria-labelledby
Landmarks that may be named
Permalink to 'Landmarks that may be named'Names are not required for accessibility compliance, but may provide additional context.
complementary
or<aside>
search
<section>
when you want it to act as aregion
landmark. Out of the box this element is not considered a landmark unless it’s assignedaria-label
,aria-labelledby
, ortitle
.
Landmarks that shouldn’t be named
Permalink to 'Landmarks that shouldn’t be named'Adding names to these could be distracting to screen readers. Instead, let their roles and content do the work.
banner
, or<header>
when it’s a direct child of<body>
(has impliedbanner
role)contentinfo
or<footer>
when either is a direct child of<body>
application
conveys information about the interface but is not exposed to screen reader users for navigation
Ways to name things
Permalink to 'Ways to name things'Accessible names are applied in several ways: with a text value (links, buttons), form label, text associated with aria-labelledby
, or an aria-label
attribute. An important bit to remember is that screen readers follow a fairly strict order of precedence:
aria-labelledby
- if this exists, no other naming attribute or text value will be read; it even overrides label elements associated with form controls.aria-label
- in the absence of aria-labelledby, this acts the same way, it takes precedence over other naming attributes and text.- When no ARIA labels are present, label elements and other attributes, like
title
, or text in the markup are read.
Some words of caution when using ARIA for labeling
Permalink to 'Some words of caution when using ARIA for labeling'ARIA labeling attributes illustrate why “no ARIA is better than bad ARIA” — they can override an element’s text value. Always test how they sound in a screen reader to ensure they accurately identify the element and match any related text/imagery that is visually displayed (that’s the gist of WCAG’s success criterion 2.5.3, label in name).
Note: Google Developers’ ARIA Labels and Relationships provides a clear and concise breakdown of how labeling attributes relate to each other.
How I name things
Permalink to 'How I name things'All of this can be a lot to remember, so I use a process of elimination to determine which naming method or attribute to apply per element/component.
1. Does it have a “built-in” way to assign an accessible name?
Permalink to '1. Does it have a “built-in” way to assign an accessible name?'Many HTML elements come with features and attributes for naming. Before considering ARIA attributes, assign names with:
- visible button or link text
- a
<label>
element properly associated with its form control alt
attributes on images- table
<caption>
elements
2. If there’s no naming feature or attribute, use ARIA
Permalink to '2. If there’s no naming feature or attribute, use ARIA'When using ARIA labelling attributes, test the rendered code in a screen reader to ensure they’re read as intended.
2a. Can a visible label be displayed?
Permalink to '2a. Can a visible label be displayed?'Use aria-labelledby
to relate an element or component to a heading element:
<h3 id="subjects-heading">Classes by Subject</h3>
<div class="accordion" aria-labelledby="subjects-heading">
...
</div>
In this example, any focusable content within the Classes by Subject accordion will be identified as belonging to that group. It’s very similar to when you focus on an input
that’s properly associated with a label
.
Before we move on, I want to reiterate that visual labels are beneficial to all users, regardless of ability. They:
- allow for a quick scan of the page to understand content priority or required steps
- help screen reader users follow along with page content
- provide labels for voice control users
- when coded with proper semantics, act as pseudo navigation for assistive tech (screen reader and voice control users can jump to headings and form controls)
- maintain context when a page is zoomed (WCAG 2.0 compliance requires that a user be able to zoom their viewport up to 200% “without loss of content or functionality”)
2b. When a visible label doesn’t work
Permalink to '2b. When a visible label doesn’t work'Sometimes a visible label would be redundant or won’t fit in the space alotted on a small screen, so a name just for screen readers will suffice. Use aria-label
directly on the component’s opening tag for:
- icons that convey meaning (not purely decorative)
- icon buttons
- any interactive component, especially when multiples exist (menus, tabs, accordions, carousels, etc)
<button aria-label="Print recipe"><span class="icon-print"></span></button>
What to name things is equally important
Permalink to 'What to name things is equally important'A good name should be brief (avoid extras like “a" or “the" unless it’s a proper noun) and not repeat the role or widget type (screen readers will include the role/element in their read out by default, i.e., VoiceOver says “Print recipe, button”).
Recommended (visible label):
<h3 id="headingID">Development resources</h3>
<div role="tablist" aria-labelledby="headingID">
Also good, when a visible label doesn’t work:
<div role="tablist" aria-label="Development resources">
Don’t do this:
<div role="tablist" aria-label="tabs">
Check your names
Permalink to 'Check your names'You can verify a widget’s accessible name and how it’s derived (text value vs ARIA attribute, for example) in the browser’s code inspector. Both Chrome and Firefox dev tools include an Accessibility panel that displays the accessibility tree and each element’s attributes:
There’s more to a name
Permalink to 'There’s more to a name'There are complexities to naming and labeling elements that I haven’t covered here for the sake of brevity. I found these articles particularly useful (and engaging), and recommend them for further reading:
- I found Joe Watkins’ Demystifying Accessible Name helpful in understanding names as they relate to the Accessibility API/tree. He also includes many concrete code examples.
- Sarah Higley’s take, What’s in a name?, should be required reading for understanding the many nuances of applying accessible names across widget types, and she covers the topic in enormously helpful detail. (Her blog is a fantastic resource for accessible coding practices in general.)
- If you’re also a specification nerd, you may enjoy working your way through the W3C’s Accessible Name and Description Computation 1.1 to better understand the recommendation for how names are gleaned from the code.
Let us know what you think!