Have screen reader pronounce all texts in the div - html

I have a div defined as below. I want the every text in the div is pronounsed as user tab into this div. In this case,
when user tabs into the outer div, screen reader reads item.X and item.Y (item is a variable).
<div tabindex="0">
<div>{{item.X}}</div>
<div>{{item.Y}}</div>
</div>
I tried to give this div a role="link", and it reads everything, but this div is not a link so I don't think it is the right approach.
<div tabindex="0" role="link">
<div>{{item.X}}</div>
<div>{{item.Y}}</div>
</div>
I also attempted to do the below, but it seems aria-label does not work with Angular Interpolation.
<div tabindex="0" role="link" aria-label="{{item.X}}">
<div>{{item.X}}</div>
<div>{{item.Y}}</div>
</div>
What is the right way to achive my goal?

It's tough to give a complete answer without seeing your real code in context. I assume the sample code is just a simplification but I'll point out the issues in the sample.
Firstly, you have a <div tabindex="0">, which allows the keyboard focus to move to that element but that element doesn't appear to do anything. It's not an interactive element. There's a warning in the html spec for tabindex.
authors should only make elements focusable if they act as interactive controls or widgets
If your <div> does do something (perhaps you have a click handler in javascript), then you'd still have a problem because your <div> does not have any semantic meaning. A screen reader will not know the purpose of the <div>. That's when role comes into play. If you designed your own link instead of using an <a> element, and your custom link was composed of <div> elements, that's when you'd have role="link" on your <div>. The purpose of the role isn't to force all the text to be read. The purpose is to convey to assistive technology (such as a screen reader) what the purpose of that object is.
As far as using aria-label, again, it depends on the semantic meaning of your element. The aria-label is typically ignored on non-semantic elements, such as <div> or <span>. See the W3 spec for "Practical Support: aria-label, aria-labelledby and aria-describedby"
In particular, the third last bullet says:
Don't use aria-label or aria-labelledby on a span or div unless its given a role.
But again, don't give a random role to your <div> just to force the label to be read.
Essentially, you are looking for the "accessible name" to be read. The accessible name calculation is well defined.
See step 2.F and 2.F.ii regarding "name from content" and looping through child elements in the DOM. But this again depends on the role.
So, in your situation, without knowing the purpose of your <div>, it's hard to give specific advice.

Maybe you need to make aria-label parse its value by doing:
[aria-label]="{{item.X}}
or am I mixing things up?

Related

How do I prevent the screen reader from saying "group" when reading this div tag's text?

On my web page, I have a div (shown below), which has text in it that I want to be read by a screen reader.
HTML
<div tabIndex={0}>
"text needs to be read"
</div>
I can hear the text is read without even providing the aria-label. However, I heard "text needs to be read group". I would like to know how can I avoid it saying "group"? I did not put a group role for the div tag.
Another example
This is another example that describes the problem much cleaner
<span class="jw-icon jw-icon-inline jw-button-color jw-reset jw-text-live" tabindex="-1" data-clicked="true">Live</span>
Run the above snippet in any browser. It makes the screen readers to announce it as "Live, group".
Is there any way to mitigate this behaviour. Expected behaviour should be like the screen readers should read it as "Live"
Lots of things going on here.
First of all, all text on a webpage is available to a screen reader and does not need tabindex="0" to make it available to be read. Screen readers provide lots of shortcut keys to navigate to different types of elements (headings, tables, lists, etc). For elements that don't have a direct navigation key, the screen reader user can use the up/down arrow keys to walk the accessibility tree (similar to the DOM).
Secondly, regarding tabindex="0", it should only be set on interactive elements. The tabindex spec says:
authors should only make elements focusable if they act as interactive controls or widgets. In addition, authors should ensure that these focusable elements have an appropriate ARIA role attribute.
And regarding ARIA roles in the second sentence in the spec quote, if your element does receive focus, if it's not a natively focusable element (such as a <a> or <button> or <input>), then it needs to have an appropriate role so that the screen reader user will know how to interact with it.
And related to this, you mentioned aria-label. The aria-label is only honored on elements that have an appropriate role. See "2.10 Practical Support: aria-label, aria-labelledby and aria-describedby".
So given all that, it's a little difficult to answer your question because your simple example is not specific enough. A <div> without a role should not read as "group". Group is usually role="region" (or <section>). The behavior you're hearing may depend on what browser you're using, what screen reader, how you're navigating in with the screen reader (tab or arrow or quicknav key).

How can I indicate to a screen reader a span element?

Context: Educational ebook (HTML + CSS) publishing
I have a composition title where I have a sentence like this:
<p>This is <del>correct</del> <ins>incorrect</ins></p>
And it is important that the user knows that some text is being deleted and some text is being inserted. I also have a related scenario where text has a highlight applied that has semantic meaning. For instance:
<p>This is an <span class="highlight-blue">adjective</span> and this is a <span class="highlight-red">noun</span>. </p>
I was recommended to use role="region" + aria-label for these situations by an accessibility consultant.
For instance:
<p>This is an <span role="region" aria-label="adjective" class="highlight-blue">adjective</span> and this is a <span role="region" aria-label="noun" class="highlight-red">noun</span>. </p>
The flexibility is necessary here because we are using a standard CSS for all of our titles and sometimes a highlight-red might indicate passive voice or it might indicate a noun, etc.
I have seen in other questions on this site that it is not allowed to use aria-label on span (or div) elements. Also using Chromevox, I have found that the reader will read the aria-label but not the text inside the aria label. (I do not have access to other screen-readers for testing.)
So my question is: What is the best way to have the semantic meaning of these inline elements read to the screen reader user?
Non-viable options
Pseudo-element with CSS hiding. I've seen solutions where you can create a pseudo-element and then hide it offscreen using CSS. When you hide content off-screen, Kindle encounters issues, dropping large chunks of text after the off-screen content, so this is not a viable option.
I would not make the highligting marks a region. That makes them a landmark, which are used to navigate to different areas on the page. The more landmarks you have, the less useful they are (because you'd have to navigate through a bunch of them to get where you want.).
There's a nice article on making highlights and other editing symbols accessible on "Short note on making your mark (more accessible)"
it is not allowed to use aria-label on span (or div) elements
That's not quite accurate. aria-label is a global attribute and can be set on any element. However, the label might be ignored if set on a <div> or <span>. See "2.10 Practical Support: aria-label, aria-labelledby and aria-describedby". In particular, the third last bullet point:
Don't use aria-label or aria-labelledby on a span or div unless its given a role.
So if your <div> or <span> has a role that is appropriate, then the aria-label will be read. But don't assign a role just to get the aria-label read. The role has to make sense.

Screen reader not reading parent's aria-label in mobile

I'm new to a11y, and have a code similar to this structure -
<div class="wrapper" aria-label="this is a group of test elements">
<div aria-hidden="true">test 1</div>
<div aria-hidden="true">test 2</div>
</div>
Behaviour on MAC chrome - Pressing Ctrl+Option+rightArrowKey puts focus on wrapper and VoiceOver reads "this is a group of test elements"
But, on mobile, aria-label is ignored.
Is there any way to focus the parent container and make screen reader read aria-label?
See "2.10 Practical Support: aria-label, aria-labelledby and aria-describedby".
A few key points (emphasis mine):
aria-labelledby and aria-describedby are robustly supported for interactive content elements such as links and form controls including the many input types.
Don't use aria-label or aria-labelledby on a <span> or <div> unless it's given a role.
So when you put a label on a non-semantic element (such as a <div>), the label may not be read unless you give the element a role. However, don't give it a role just to get a label read. Make sure the purpose of that container really requires a role that should be conveyed to screen readers.

JAWS does not read aria-label for span inside header with aria-label

I have a span which serves as a button which is inside a header:
<h3 aria-label="Header Aria Label">
<span tabindex="0" aria-label="Span Aria Label">Button</span>
</h3>
However, whenever I tab to the span, it reads "Header Aria Label". How do I force JAWS to read the aria-label in the span?
First of all, please don't be offended but what you are doing is poor design, at least, accessibility-wise.
A button inside a heading (not a header, BTW, in HTML 5 there is a separate <header> element which is a quite different thing from <h3> you use here) is a bad idea. Really.
But anyway, if you want JAWS to treat your span as a button, either:
Use a native <button> element, or
Use role="button" on your span, otherwise JAWS wouldn't know in any way that this particular span should be treated as a button. But please prefer the first method unless you absolutely have to use a span here. And please, pull it out of your h3, this will be far more accessible.
A span is neither landmark nor interactive content. An aria-label will not be read by a screen reader (and rightly so).
Instead, use a <button> element. That will address your problem, and be more accessible.
I encounter similar issues to this. From my experience it doesn't seem to make any difference whether it's a span, a div or other tag. Even when multiple aria attributes are applied such as role and aria-hidden="false", the aria-label is not always read out. To me, the condition for aria-labels to be read by JAWS seems to be based on some other rule(s). It would be helpful to see the conditional flow of when an aria-label is read by JAWS. I'm guessing only someone with access the the JAWS source code would really be able to answer this. In the meantime I'll keep trying different things to try to get it to work. JAWS finds the element in the DOM, because it can read the inner html (such as reading the word "Button" in the example above). I'm wondering if the decision to read the aria-label is based on it's parent structure, roles and attributes.

Can I have a header work as a button but not use the role of a button

I have a header that I want to work as a button. My problem is that if I assign the header a button role, it messes with accebility and a screen reader; The button role overrides the header so the blind user can not navigate to the header as they would with other headers.
I want the user to be able to navigate to the header and push it like a button (using the space bar). I have been trying to nest a button into the header with a changed tab index but it does not work.
<h2 class="navigation_title" tabindex="0">
<span role="button" class="navigation_title_text" tabindex="-1">
</span></h2>
Any ideas of how I can have a header work as a button but not use the role of a button?
What's wrong with this? Simplify everyone's lives by using a real <button>:
<h2 class="navigation_title">
<button class="navigation_title_text">
Foo
</button>
</h2>
<script>
$('.navigation_title_text').click(function () {
...
});
</script>
I interpret the question so that you have assigned some scripted event to an heading element and you would therefore want to assign the button role to it, in addition to the default heading role. And this is meant to improve accessibility so that the element would be treated both as a heading, e.g. in “headings reading mode”, and as a button, e.g. so that assistive software could inform the user about a button that can be activated.
According to the WAI ARIA spec, the role attribute allows a space-separated list of role identifiers as its value, but only the first one is used. So setting role="heading button", while formally allowed (HTML5 validators have a bug that reports it as an error), is taken as identical with role="heading". This means that you can only one role for an element instance.
(Moreover, W3C HTML5 Rec defines h2 so that the only allowed roles are heading, tab, and presentation.)
You can wrap a span inside an h2 element as in the question, or an h2 inside a div, and declare the role of the span or div element to button. However, this makes one the elements a heading and another element a button, in WAI terms. The situation that you cannot assign a single element two roles reflects implementations: they cannot be expected to handle the same element in two ways.
From a more general accessibility point of view, considering also cognitive problems, this is reasonable: Even if you could make an element act both as a heading and as a button (as you technically can, up to a point, but not in WAI sense), users would have a cognitive challenge. When they encounter something that walks like a heading, talks like a heading, they won’t expect it to to a push button as well.
Given the abstractness of the description, it is impossible to suggest other approaches. But a solution might consist of simply having a button, with short text, after each heading (possibly on the same line).
<h2 class="navigation_title" tabindex="0">
<span onclick="myFunction()" class="navigation_title_text" tabindex="-1">
</span></h2>
By using onclick attribute you make this element clickable
My function could be anything you like