A man sitting in front of a computer with Snowdog's logo in the top-right corner and accessibility logo below.

Reviewing the accessibility of web solutions, I've noticed that missing accessible name is a common issue. It often appears in buttons and links that do not have visible labels and have icons/images as content. It makes elements not visible to all users and for certain assistive technologies (ATs). Adding an accessible name is an easy and quick fix, but we have to follow some rules to make it valid.

What are naming techniques and how to use them? What is the difference between aria-label and aria-labelledby? What are common developers' mistakes and how to avoid them? I try to cover all of this to help you write more accessible code.

Accessible name—the basics

An accessible name makes an element visible and understandable for all users, also for those who use assistive technologies. It improves the semantics and often the structure of the website, user agents use it to create accessibility trees, and it's valuable information for indexer robots, so it impacts SEO. Missing an accessible name can completely block users' interaction.

We have several naming techniques that we can use:

  • Child content (static text content, alt attribute for image…)
  • aria-label attribute
  • aria-labelledby attribute
  • native markup elements, ex.: label, caption, figcaption...

When an accessible name is not implemented using native markup (HTML content) or one of the primary techniques (e.g., the aria-label or aria-labelledby attributes), browsers calculate an accessible name from other attributes as a fallback mechanism. Because the attributes used for this calculation are not intended for naming, a name itself it's usually of low quality and ineffective.

Which elements required a name?

According to WCAG (Web Content Accessibility Guideline), all focusable, interactive elements, dialogs, and some structural containers should have an accessible name. Many other elements can be named, but whether a name will enhance the accessible experience depends on context.

Important! Name for generic role elements, like div and span is not allowed. It's also prohibited in a paragraph.

If you need to add a name to the container, you need to set a specific role for it.

Here you can find a list of ARIA roles with information if a name is required, recommended, or not allowed: Naming role guidance table

Naming techniques

Child content

Certain elements get their name from the content, for example: buttons, links, and headings. The best way is to use a visible name that is coherent for all users and AT (Assistive Technologies).

  

The full list of elements that get a name from their content you can find here: Naming with child content

Native markup elements

The best practice is to use native markup to name HTML elements:

  • From fields - use label for form fields: input, textarea, select
  • Use legend for fieldset element
  • Use caption for table
  • Use figcaption for figure

aria-label

aria-label attribute allows adding a name to an element that is not visually rendered. A value of the attribute is a name in the form of a string.

It works in 2 different ways, depending on the role of the element:

1. If you add it on an element that supports naming from children's content, it overrides the content and hides it from ATs, for example:

  

2. If added on any other element (on which is allowed), both, aria-label value and element content are rendered, for example:

  

aria-labelledby

aria-labelledby attribute, similar to aria-label, allows adding a name for an element but instead of typing a name in an attribute value directly, uses another element and binds it with its id. With this attribute, you can reference hidden elements too, for example:

  

With aria-labelledby, you can reference multiple elements to use their content as a name. You can also reference the element itself. Content will be concatenated, for example:

  

In the above example, the name will be: "Download ebook PDF, 2.4 MB" (yes, with space before "PDF, 2.4 MB"!)

both aria-label and aria-labelledby used on the element which supports naming from child content (ex. button, links), it overrides the content of an element and hides it from ATs. When you use aria-label or aria-labelledby on a button or link with visible text, the name value should match the visible text or at least start with visible text (it's required by WCAG SC 2.5.3). It is required for using speech-recognition technology - speech input users rely on visual labels when using voice commands. If you reference an element in the aria-labelledby attribute's value more than once during a name calculation, the second and any subsequent references will be ignored. The aria-labelledby attribute cannot be chained, you should reference an element with content, not with another aria-labelledby attribute.

Visually hidden text

Instead of using additional attributes, you can add visually hidden text which is rendered for ATs. This popular technique is easy to implement and works easily with Tailwind class sr-only. Using it you can add an accessible name but only in elements that support naming from child content (ex. button or link) or an additional description.

If you don't use Tailwind, you can use the following CSS code:

  

Example as an accessible name:

  

Example as a description:

  

Don't do it! Common developers' mistakes

  • Don't overuse aria properties for adding names. Remember not every element needs aria-label. When possible, use a native HTML solution, not ARIA.
  • Don't use aria-label on div, span and paragraph. Check if ARIA name property is allowed on a specific element. You can use automatic tools in the browser—axe devtools, lighthouse, or check accessibility in devtools.
  • If you overwrite an element's content using ARIA property, test it.

Tips to write clear accessible names

  • Use names for functions or purposes, not forms. For example, if a close button has an X icon, use "Close" text not "X".
  • Put the most important words first, if an element enables an action, use a verb at the beginning.
  • Use short and clear names (for most cases, 3-4 words should be sufficient).
  • Do not include roles and element's name inside a name value (like "button", "image" or "navigation"), this role will be announced with AT
  • Start a name with a capital letter, it helps some AT to announce it properly
  • Use aria-describedby for additional description. It works similarly to aria-labelledby. It allows adding a description to an element by binding another element by its id. You can also reference a hidden element.

Some specific cases

Multiple elements with the same action—ex. in the product list

Often on a category page, in the product listing, you have the same actions, with the same label (or icon) or different products.

Why is it an issue?

When AT user reviews a page using buttons or links, he sees multiple "Add to cart" links

Solution?

You can use aria-label with the product name after the action name or visually hidden text inside the action link/button:

  

You can also use aria-labelledby but you need to use unique ids which can provide additional complication in code, so I don't recommend this approach.

Image inside a button or a link—does an alt attribute work as an accessible name?

Yes, if you use an image as a content of a link or a button, you can use its alt attribute to set an accessible name, for example:

  

You can also hide an image inside and use aria-label or hidden text, for example:

  

  

I recommend using aria-label or hidden text solution, for the following reasons:

  • Some automatic tests detect a link with an image and without an additional name as an error. In this case, you can avoid additional discussion with a client, while he runs an external accessibility scanner
  • You and other devs that maintain code need to remember to adjust image alt to link destination, not to image representation, even if it's evident to you, it doesn't have to be clear for junior dev or content manager, a name added for a link is easier to maintain in this case

Title attribute 

Any HTML element can have a title attribute specified. It is presented visually as a tooltip when the user hovers over the element with a pointing device, which is not particularly discoverable and is also not accessible to visual users without a pointing device. It can be used as the element's fallback accessible name but remember that some ATs or devices agent can omit it. It is recommended to use the explicit labelling techniques described above.

What about an additional description—⁣aria-describedby?

The aria-describedby property works similarly to the aria-labelledby - it allows adding a description to an element by binding another element by its id. It also allows referencing hidden elements.

Screen readers present descriptions last, sometimes after a slight delay. Some screen readers do not announce descriptions by default but instead, inform users of their presence so that users can press a key that will announce the description.

How to test an accessibility name?

You can easily check your accessibility name during development. You can use tools directly in your browser:

1. Make a quick scan using an automatic test. It allows you to find where the accessible name is missing and if applied aria roles are allowed on the specific element.

Use browser extension—Axe DevTools or IBM Accessibility Checker to detect issues.

Axe DevTools example:

axeDevtools browser extension example - investigating an issue

Accessibility checker example:

Accessibility checker browser extension example - investigating an issue

2. You can review the accessibility tree generated from your code and check the accessibility properties of the element in DevTools:

Check how to use the accessibility pane in DevTools in this guide.

More resources: