What’s in a name?

People who use assistive technologies, such as a screenreader or speech-recognition software, need to know the names of interactive elements on the web. Otherwise they may not be able to recognise the thing they’re dealing with, and so be unable to interact with it.

Which means we, as authors, need to give things meaningful accessible names. How does this happen?

Under the hood

Browsers (and, through them, assistive technologies) get accessibility information through something called the accessibility tree. This is a kind of stripped-down version of the Document Object Model (DOM), a representation of the web page that browsers use to render the page.

While the DOM contains everything needed to render the page, the accessibility tree doesn’t need to know about things like styles, colours, fonts, and shapes. Instead, it focuses on four things:

  • description
  • role
  • state
  • name

It’s the last of these, the name, that assistive technologies use to announce things. But how do they get them?

Naming HTML elements

Not all HTML elements need an accessible name. Headings, paragraphs, lists and so on are just text, which assistive tech already has access to. Elements that must have an accessible name include:

  • links
  • buttons
  • form inputs
  • images

This is not an exhaustive list. For example, a legend inside a fieldset will serve as the fieldset’s accessible name.

Browsers determine the accessible name by checking for these things and, crucially, in this order:

  1. aria-labelledby
  2. aria-label
  3. Native HTML elements (such as a caption, label, or alt)
  4. The element’s text content
  5. title attribute

Browsers look for each of these in turn. As soon as they find one, they stop.

The first two are what’s known as ARIA attributes. ARIA is a specification layered on top of HTML to improve the accessibility of very interactive pages or web applications.

However, it’s generally best to use a native HTML name if you possibly can. Indeed, it’s often said that “the first rule of ARIA is don’t use ARIA” (although that should really have “unless you absolutely have to” added to the end).

Let’s take a look at how things get their accessible names.

Links

The best, simplest and least error-prone way to name a link is simply using its text.

This is my accessible name
 <a href="#">This is my accessible name</a>Code language: HTML, XML (xml)

So when a screenreader focuses on this link it will read out “Link: This is my accessible name.” This is one of many good reasons why you should never have link text like here. Instead, use descriptive text, and make each link description unique.

We can overrule this by adding an aria-label.

Don’t do this

This is not my accessible name
<a href="#"aria-label="My new name">This is not my accessible name</a>Code language: HTML, XML (xml)

This link’s name is now “My new name”. But remember the first rule of ARIA. The accessible name is now very different to the visible label. This can be very confusing: many screenreader users also visually process the page, so if what’s announced differs from what’s on screen, it’s a jarring experience.

And for people using speech recognition software, this would be extremely bad. To ‘click’ the link, they need to use its accessible name. But if they say “Click ‘This is not my accessible name'” their software will not recognise the link.

It’s also a violation of WCAG 2.5.3: Label in name. So, don’t use ARIA unless you really have to.

Buttons

Buttons are the web’s Action Men. You click them, things happen – a dialog opens, a form submits, a train ticket gets bought (and your bank balance goes down).

Like links, the best strategy is to KISS:

<button>Do a thing</button>Code language: HTML, XML (xml)

The accessible name of this button is “Do a thing”.

If you just use native HTML elements like this, you get lots of free stuff out of the box.

  • An accessible name
  • A role=button
  • A state (default)
  • It’s focusable
  • It’s findable

Now you can, technically, make something that is not a <button> behave as a button. But to do that, you’d need to do something like this:

<div class="button" role="button" aria-label="Do a thing" tabindex="0">
Do a thing</div>Code language: HTML, XML (xml)

You don’t have to know anything about web development to be able to see that that’s a lot more code than the <button> example earlier. And, as a general rule, less code is good.

So you’ve once again introduced the risk of the accessible name (provided by aria-label) differing from the label (i.e. the visible text). As well as giving yourself a ton of CSS and javascript to write and maintain, just to make your not-a-button look and act like a button.

Form inputs

Obviously, everyone submitting data using a form needs to know what they should input into each field.

Just as with links and buttons, the best way to do this is to use the visible label. But form inputs have explicit labels:

<label for="firstname">First name</label>
<input type="text" id="firstname"></input>Code language: HTML, XML (xml)

For this to work, the value of the label’s for attribute has to exactly match the id of the input it names.

It used to be common for labels to be implicitly associated with their input by nesting the elements like this:

<label>First name
<input type="text"></input>
</label>Code language: HTML, XML (xml)

This mostly still works but support is not 100% guaranteed in some assistive technologies. Better to stick to the explicit method.

I have seen examples like this in the wild:

<label for="firstname" id'="firstname_label">First name</label>
<input type="text" id="firstname" aria-labelledby="firstname_label"></input>Code language: HTML, XML (xml)

This works and is accessible, but it’s completely redundant.

As well as automatically gaining focusability, role and so forth, this has another benefit: the label can be clicked to activate the control, so giving it a much greater clickable area. This is particularly useful for smaller controls, like radio buttons, which can be fiddly for people with tremors or poor motor control.

Click the labels below to see it.

Pick an option
<fieldset>
<legend>Pick an option</legend>
<input type="radio" id="opt1" name ="options" />
<label for="opt1">Option one</label>
<input type="radio" id="opt2" name ="options" />
<label for="opt2">Option two</label>
</fieldset>Code language: HTML, XML (xml)

Confusingly, the name attribute on the radios does not contribute to the accessible name. It’s easy to see why, if you think about it: both radios in the example above whould have the accessible name “options”, so it would be impossible for someone using a screenreader to understand which was which.

Images

Images, uniquely, don’t have a visible label. The best way to name this is using the alt attribute:

<img src="/picture.png" width="800" height="600"
 alt="A description of the picture">Code language: HTML, XML (xml)

So this image’s accessible name is “A description of the picture”.

This is one reason why it’s a good idea to keep alt text reasonably brief. Screenreader users can, and do, ask their software to give them an overview of a web page: all the headings, or all the links, or all the named things. If you have 12 images all with long alt text, that can quickly become an unnecessarily verbose experience.

If you need to provide a more detailed description of the image, it’s better to use another technique, such as a caption.

<figure>
    <img width="1374" height="278" src="/img.png" 
alt="A screenshot of HTML code showing markup for a picture element">
    <figcaption>Modern web design includes a variety of techniques 
to provide text alternatives for non-text content. 
In this example, a caption provides additional context</figcaption>
</figure>Code language: HTML, XML (xml)

Again, there’s no need for aria-labelledby here. The fact that the image and caption are children of the same figure is enough to make the association.

If you want to delve further into providing text alternatives for non-text content, we’ve got you covered,

I'm a service designer in Scottish Enterprise's unsurprisingly-named service design team. I've been a content designer, editor, UX designer and giant haystacks developer on the web for (gulp) over 25 years.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.