I was having troubles finding the answer to this online! I understand that the ‘id’ attribute uniquely identifies a component on a website/web app. In examples of ‘accessible’ buttons, they always have the ‘id’ attribute, but I’m currently struggling to explain to my dev team why it is required.
My assumption is that the ‘id’ may be used by assistive tech like ‘speech input’ devices to identify what component the user is trying to operate, but without access to a device like this I can’t confirm! Our buttons don’t currently use the ‘id’ attribute but are announced as I would expect by screen-readers and don’t show any issues in tools like AXE.
I’m familiar with the WCAG criteria ‘label in name’ but it does not explain where the accessible/programmatic name actually comes from!
Specificly ‘id’ is not required. You can use any tag/attribute you want in hope they are unique.
We even introduced a specific element ‘testid’ which is unique and only available on our test environment. In order to do some easy UI checks.
That’s okay and sometimes normal, I want to say it’s not a standard use in Angular but I’m not sure anymore, it’s been to long to tell
This is also not always true. I’ve had many instances where an ID was found multiple times. Which was expected behavior.
The HTML specification states that “id” attributes must be unique. See HTML Standard
Depending on what an “id” attribute is used for, the page may still work ok if it is not unique. For instance, if you are using it as a CSS selector (although you ought to use a “class” if you want to target multiple elements).
We usually tolerate duplicate “id” attributes if only one instance is displayed at any time and all the others are hidden using “display:none”. This is quite common with navigation menus if there is separate code for the desktop and mobile menus. Obviously, the two menus would never be displayed at the same time.
To answer the original question, buttons do not need “id” attributes for accessibility, but they may well have “id” attributes for other reasons. For instance, if you want to target the button using JavaScript to disable it under certain circumstances. Also, “id” attributes will be needed for test automation.
Label in Name
The easiest way to find the accessible name is to look in the Accessibility tab for the element in the DOM Inspector. If you are familiar with the Accessible Name Computation - see https://w3c.github.io/accname/ - you can work out the accessible name by reading the code. There is a hierarchy, for instance an “aria-label” attribute overrides the element’s contents, which overrides the “title” attribute, but it’s way more complicated than that. The DOM Inspector does that calculation for you.
I’m no pro at this stuff, Kris and Steve seem to have it covered. But I suspect that many other folk may have some further hints on how to be more confident. If you have a MOT Pro subscription I could point you to some of the articles and recorded talks over in the members area for inspiration ways to test this Claudia .
I’m not trying to sell it, but this is the best content the web has even if it is behind a paywall, get your boss to sign you up. I’m not a salesperson, I just love how the club is where the gold lies for me.
Screen readers rely on labels to describe things so any button which is unlabelled may announce what is on the button, e.g. submit, but not that it is a button or what will happen when it is activated.
This falls under * 2.4.6 Headings and Labels: Headings and labels describe topic or purpose. (Level AA).
Good info here with an example of how to inspect in dev tools. https://www.sarasoueidan.com/blog/accessible-icon-buttons/#accessible-button-names
You should also check your buttons have distinctive shapes, high colour contrast in all states, hover, keyboard focus, activated, and clear labels.
Hi @claudia.davey Great question! Firstly, I believe WCAG refers to test inside the button and, especially if button is an icon, aria-label attribute. This is because the screen readers would use that exact data to read the screen. Therefore, your tests should also rely on the same exact information to refer to the button (including relative locations/indexes if the button is not unique). It is most easily done with the tools like testRigor where you can write instructions like click "Button text" or click "whatever is in aria-label". Dislaimer: I’m associated with testRigor.
Screen readers announce the name that results from the Accessible Name Computation I mentioned above. The best way to label a button is to provide text contents, in which case the visual label is the same as the accessible name.
Although you can use the “aria-label” attribute to label buttons, it should not be your first choice. The ARIA specification itself states that “The first rule of ARIA is don’t use ARIA”. If you can achieve the required result without ARIA, then do so.
In the case of a button with an icon, use text that is hidden using the “clip” technique. One of the benefits of this approach is that the text label is displayed instead of the icon if the CSS fails to load for any reason. If you used an “aria-label” attribute, your button would have no visible label if that happened.
One of the risks of using an “aria-label” attirbute is that it is given a value that does not match or contain the visible text label, in which case you fail WCAG SC 2.5.2 (Label In Name).
You are mixing up the role and the label. If a button is unlabelled, it will still be announced as a button because that is its role.
If a button has the visible label “Submit”, then that will also be its accessible name unless it is an image of text (which would be crazy) or if it is overridden by something with higher priority in the Accessible Name Computation, such as an “aria-label” attribute. For the button to be unlabelled, it would have to have an empty “aria-label” attribute or an “aria-labelledby” attribute that points to an empty string.