Slide instructions

SPACEBAR to move forward through slides.

SHIFT & SPACEBAR to move backwards through slides.

LEFT ARROW & RIGHT ARROW to move through sections.

ESC to see overview and ESC again to exit.

F to enter presentation mode and ESC to exit.

Accessible names

Experience the pain first-hand

What is an accessible name?

Accessible names are the labels announced by assistive technologies for elements.

Buttons, links, form fields, images, tables, form groups, and many other elements can all have accessible names.

But sometimes there’s no accessible name, or multiple possible names.

What happens when there are multiple possible names for one element?

Here is a simplified breakdown of how accessible names are decided:

  1. aria-labelledby
  2. aria-label
  3. Native HTML mechanisms
  4. title
  5. placeholder
  6. no accessible name

The game

Rules:
  1. I‘ll put a code example on screen.
  2. You have to determine the accessible name for that element.
  3. Yell out your answer before anyone else to win chocolate!

Example 1: what’s the name of the button?

<button></button>

Answer: No accessible name

The button has no content and no labelling attribute, so there's nothing to announce.

Example 2: what’s the name of the button?

<button>Submit</button>

Answer: Submit

Visible text content inside a button is its accessible name by default.

<button>Submit</button>

Example 3: what’s the name of the link?

<a href="#">
  <svg>
    <title>Hello</title>
  </svg>
</a>

Answer: Hello

An SVG <title> acts as the text content of the SVG, so the browser treats it the same as visible text inside the link. The accessibility tree will show it as coming from contents.

<a href="#">
  <svg>
    <title>Hello</title>
  </svg>
</a>

Example 4: what’s the name of the button?

<button aria-label="Close">
</button>

Answer: Close

The aria-label directly on the element sets the name, overriding the empty content.

<button aria-label="Close">
</button>

Example 5: what’s the name of the link?

<a href="#" aria-label="Goodbye">
  <svg>
    <title>Hello</title>
  </svg>
</a>

Answer: Goodbye

The aria-label outranks <title> inside a child SVG, so Goodbye beats Hello.

<a href="#" aria-label="Goodbye">
  <svg>
    <title>Hello</title>
  </svg>
</a>

Example 6: what’s the name of the input?

<label>Search the site</label>
<input placeholder="Search">

Answer: Search

The <label> is not associated with the input (no for/id pairing), so it's ignored. The placeholder is the only thing left.

<label>Search the site</label>
<input placeholder="Search">

Example 7: what’s the name of the button?

<button aria-labelledby="x" aria-label="Close">
  Cancel
</button>
<span id="x">Delete</span>

Answer: Delete

The aria-labelledby beats aria-label every time, and it points to the <span> containing "Delete".

<button aria-labelledby="x" aria-label="Close">
  Cancel
</button>
<span id="x">Delete</span>

Example 8: what’s the name of the input?

<label for="fish">Fish</label>
<input
  type="text"
  id="fish"
  aria-label="dog"
  title="rabbit"
  placeholder="fox"
>

Answer: dog

The <label> is properly associated via for/id, but aria-label sits higher in the pecking order and wins.

<label for="fish">Fish</label>
<input
  type="text"
  id="fish"
  aria-label="dog"
  title="rabbit"
  placeholder="fox"
>

Example 9: what’s the name of the button?

<button>
  <img src="cross.png" alt="Hello">
  <span class="hidden">how are you</span>
  <span role="img" aria-label="doing"></span>
  <span role="img" aria-labelledby="aaa"></span>
  <span role="img" title="?"></span>
</button>

<p id="aaa" style="display: none;">today</p>

Answer: Hello how are you doing today ?

Buttons use “name from contents”, meaning their accessible name is built from the accessible text alternatives of descendant content. Different child elements can contribute text in different ways, and the final name is concatenated together.

The image provides alt text: "Hello"

Even though visually hidden, the first <span> provides text: "how are you". Buttons build their accessible name from descendant content, so visually hidden text can still participate in the button’s name calculation. This works because the content is visually hidden only. It would not work if the element used display: none, visibility: hidden, or aria-hidden="true".

The second <span> has a role of img and therefore provides a name via aria-label: "doing"

The third <span> has a role of img and therefore provides a name via aria-labelledby: "today"

The fourth <span> has a role of img and therefore provides a fallback accessible name via the title: "?"

The space before "?" comes from how the browser computes accessible names. Each child element’s contribution is usually separated by a space when the final name is concatenated together. So the <span role="img" title="?"> contributes its own separate text token, producing "today ?" rather than "today?".

<button>
  <img src="cross.png" alt="Hello">
  <span class="hidden">how are you</span>
  <span role="img" aria-label="doing"></span>
  <span role="img" aria-labelledby="aaa"></span>
  <span role="img" title="?"></span>
</button>

<p id="aaa" style="display: none;">today</p>

Takeaways

  1. Accessible names follow predictable rules.
  2. It becomes easier once you understand these rules.
  3. You can quickly test names using the accessibility tree.

Here is a live demo of all the examples we explored in case you want to review later.