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

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.

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).

Have screen reader pronounce all texts in the div

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?

Aria-label on div styled as image

In table cell I have a <span> element, that is styled as image and displays state of interface (Enabled/Disabled/Error), based on it's color.
For users with proper vision, it is compact and understandable. I don't want to change it. But as there is no text in this span, it is not read by screen reader. (understandable, but problem)
What is the correct approach to handle such elements for screen readers?
Expected solution would be to add aria-label with text for screen reader, but, as I found in other topics, "aria-label does not work on <div> nor <span>". As I tested it on JAWS 15, it is true, but in JAWS 18 such labels are being read just fine (why?).
Also I tried to add role="img" to this span, and to add text in aria-label and/or alt and/or title with no result in JAWS 15.
What do you mean by "normal users"? Are you talking about sighted users compared to low-vision users? The latter are normal users too.
For low-vision users, yes, an aria-label is normally the way to go. Thank you for considering accessibility issues.
But you'll also have an issue for color deficient users. Those that can't distinguish between certain colors. Is color the only means for conveying the state of the object? Is there an associated icon too? Color-deficient users won't be using a screen reader so won't benefit from an aria-label.
It's not clear in the html or aria specs on the default role of a <span>. The aria-label should be used in the accessible name calculation and step 2D says only if the element is presentational (meaning role='presentation' or role='none') should the aria-label be ignored. So, if a <span> is considered presentational, then its aria-label will be ignored. JAWS seems to be interpreting it this way but NVDA does not. NVDA in firefox will read the aria-label of a <span>.
So your best choice might be to give the <span> a role, such as role='img' or role='note', so that you can give it an aria-label too, but that will also cause the role of the span to be announced.
Or as one commented above, use a real <img> with alt text.

HTML5 i tag validity with icons

I have been using Bootstrap to build my site, but in doing so and researching SEO, I've discovered that using the i tags with glyphicons is not technically "valid" HTML. Is there a definitive rule that says that i tags can be used in this way without effecting markup validity without effecting SEO?
As part of this issue, I am also trying to satisfy a complaint that my anchor text does not describe its destination:
<a href="#Url.Action("Accountant", "Service")">
<div class="service-icon">
<div class="icon-book-1 icon-medium-effect icon-effect-2"></div>
</div>
</a>
This produces the desired visual effect, however I can't add anchor text else it will obviously be displayed on the screen. Normally an image would have been used within the anchor and I could have displayed alt text, so I'm stuck as to where best to put this "descriptive text".
Don’t use i.
The i element has a meaning which isn’t appropriate for general icons:
[…] a span of text in an alternate voice or mood, or otherwise offset from the normal prose in a manner indicating a different quality of text, such as a taxonomic designation, a technical term, an idiomatic phrase from another language, transliteration, a thought, or a ship name in Western texts.
Reasons why some people use(d) i as hook for showing icons (via CSS) might be:
The term "icon" starts with i.
The element name is short.
Use span instead, which is a meaningless element.
If the icon is relevant content (important for understanding/using your page), consider using the img element instead, which allows you to use the alt attribute.
You should use CSS for decorative icons only. If that’s not possible:
If you link this icon and the link doesn’t contain any content (no text, no img, …), i.e. it only contains an empty element, then you should provide some content in the HTML. Otherwise, visitors without CSS support, screen reader users, etc. won’t be able to use your link. If you don’t want to include content for design reasons, hide it visually. More details in my related answer.
You can use something like <span class="sr-only">Your Text</span> to improve the accessibility.
.sr-only is a built-in Bootstrap class to make it easier to provide useful text to screen readers when you also do not want that text to appear visually on the screen.

Alt or title attribute for i tag

I use font-awesome and display their fonts like that:
<i class="icon-lock"></i>
This will display a nice little lock symbol. For the user to know what exactly that means, I tried adding attributes such as title and alt, but to no avail.
Is there any attribute I can use for the <i> tag that executes the same task as alt for images and title for links?
You can use the title attribute on an i element, like any element, e.g.
<i class="icon-lock" title="This symbolizes your being locked inside"></i>
Whether it helps is a more difficult issue. Browsers usually show the title attribute value as a “tooltip” on mouseover, but why would the user mouse over the icon? And such tooltips are of poor usability; so-called CSS tooltips often work better.
Screen readers may give the user optional access to title attributes, but I’m not sure what they do with elements with empty content.
With the advance of WAI-ARIA, when using font icons, you probably should use a combination of the following to improve accessibility:
The role presentation to remove implicit native role semantics of the element. This is especially important if you (ab)use an element with a native semantic to provide icons, as this is the case in your example using the i element (which, according to the specs, "represents a span of text in an alternate voice or mood [...]").
An aria-label to provide a string value that labels the element -or- a native HTML title attribute if you are OK with the browser displaying a tooltip when hovered.
An aria-hidden attribute to hide generated content from assistive technologies (as you are using an icon font family, there is a generated character :before of :after). According to the specs:
Authors MAY, with caution, use aria-hidden to hide visibly rendered
content from assistive technologies only if the act of hiding this
content is intended to improve the experience for users of assistive
technologies by removing redundant or extraneous content. Authors
using aria-hidden to hide visible content from screen readers MUST
ensure that identical or equivalent meaning and functionality is
exposed to assistive technologies.
I don't know your exact use case, so I take the liberty to use the simpler case of providing a phone number. In decreasing order of preference, I would use:
<span aria-label="Our phone number">
<span class="icon-phone" aria-hidden="true"></span>
+33 7 1234576
</span>
(or any variation implying:
- an `i` element with a `role` presentation attribute
instead of the inner `span` element
- a `title` attribute instead of an `aria-label` attribute)
<span class="icon-phone"
aria-label="Our phone number">+33 7 1234576</span>
(or any variation using `title` instead of `aria-label`)
<i class="icon-phone" role="presentation"
aria-label="Our phone number">+33 7 1234576</i>
(or any variation using `title` instead of `aria-label`)
Please note that aria-label and title attributes should describe the content of the element. Not the next sibling element. So I feel like the following solution is not in accordance with the specs (even if most accessibility tools would actually have the same observable behavior as if the phone number were actually inside the span element) :
<span class="icon-phone"
title="Our phone number"></span>+33 7 1234576
You should use <span> or something along those lines instead. You can use the title="" attribute to give some text on hover, if that's what you're looking for. As far as providing accessability to screen readers, or SEO value, you could add the following CSS:
.icon-lock{
text-indent:-99999px;
}
And then write your markup like so:
<span class="icon-lock">What I want the screen reader to say</span>
I think the role for fonts that act like images should be reserved to role="img". This can then be used with aria-label="alt-text". It works because of the ARIA Accessible Name algorithm. See: Aria Techniques Using Img Role.
<i> tags are for marking up text. You are changing the semantic meaning of this tag to something that has nothing to do using italics (and even the italic tag is a bad idea).
You should be using a SPAN instead.
Italic elements do not support alt attributes, IMG elements do. If you want an ALT attribute, use an image.