(This question is similar to Should ARIA labels provide context?, but not identical, as I'm talking about buttons and do not have full control over the markup.)
I have some amount of items and buttons that act on those items. Here's a simplified example:
<ul>
<li><span>Item: foo</span> <button>remove</button></li>
<li><span>Item: bar</span> <button>remove</button></li>
<li><span>Item: baz</span> <button>remove</button></li>
</ul>
As far as I understand, when someone using a screen reader tabs through the page, they will be read the button text but not the item text. This doesn't seem ideal to me, as they don't have context on which item the button will remove.
Assume that I don't have full control of the markup; I can only add attributes.
What is the best practice in this situation?
- add an
aria-label
to the button that gives more context:<button aria-label="Remove item foo">remove</button>
- make the item text itself tabbable and give it an
aria-label
so it's read aloud:<span tabindex="0" aria-label="Item foo">Item: foo</span>
- leave things as they are, because this is intended behavior and/or I'm misunderstanding something about screen readers
- something else entirely?
CodePudding user response:
The answer depends on if you're trying to conform to the Web Content Accessibility Guidelines and are only worried about compliance issues (from a legal perspective), or if you want to have a great user experience regardless of whether you conform or not.
The first part, conformance, is a little tricky. Regarding context, 2.4.4 Link Purpose (In Context) comes into play but only for links. The guideline says the text for a link is ok if the user can figure out the meaning of the link from the link text and the surrounding context (such as what text is before or after it). And then context is defined as the link being in the same list item (<li>
) as the surrounding text.
So that sort of fits your scenario, but you have buttons instead of links, so WCAG 2.4.4 doesn't really apply to you.
There isn't a clear guideline for the context of buttons except WCAG 2.4.6 Headings and Labels. It says that the label [of a button] must describe the purpose of the button. So who decides whether the label is descriptive enough? That's a tough call. Is "remove" descriptive enough? Maybe, maybe not. It kind of depends who you ask.
So if you are focusing on a great user experience rather than conformance to WCAG, adding context to the buttons is a really good thing.
You are correct that if a screen reader user tabs through the interface, they will only hear the button label and not the list context. But screen reader users have many ways to navigate a webpage. One option is to navigate by list elements (<ul>
or <ol>
) by using the L key (JAWS and NVDA). Another is to navigate by list item (<li>
) by using the I key. (That's the letter 'i', not a number 1). So a user can navigate to your list items, hear the text of the list and the text of the button and get some context.
I would not recommend your second idea of adding tabindex
to the list. You don't want the user to tab to elements that are not interactive.
Adding more context via a label is the best approach. I would recommend using aria-labelledby
before resorting to aria-label
. If you have an element in the DOM already that has the text context you need, give that element an ID and then refer to that ID in the aria-labelledby
of the button. It's a little more work but then you don't have to worry if you change the text in the list because the button is using an indirect reference and will automatically pick up the new text.
You'll also need an ID on the button and then you have the button point to itself and to the context. That sounds confusing but here's all it is:
<ul>
<li>
<span id='item1'>Item: foo</span>
<button id="button1" aria-labelledby="button1 item1">remove</button>
</li>
<li>
<span id='item2'>Item: bar</span>
<button id="button2" aria-labelledby="button2 item2">remove</button>
</li>
</ul>
A simpler approach is to use aria-label
as in your first suggestion but I don't like repeating text in an aria-label
that's already in the DOM. If your list text changes at some point, you have to remember to change the aria-label
too.
CodePudding user response:
Making the span focusable is a very bad idea unless it produces an action itself when clicked. Only elements that are actually interactive should be focusable. It's very confusing for the user is something is focusable but don't provide any interaction when focused.
Adding context with aria-label is a good idea, but in fact there is better. The recommended way is to add off-screen text instead:
<button>Remove <span >Item 123</span></button>
Where .sr_only is a CSS class present in many frameworks with different names (sr_only, visually-hidden, etc.) which send the text off-screen. It is invisible for normal users, but read as normal by screen readers.