I have an image
<img src="sample.jpg" alt="sample">
which is reading as LINK GRAPHIC by JAWS, I have to make JAWS to read as Sample Image.
Why would you try to make JAWS read something in particular?
The important part is the information and content your page is giving to your users. What's the purpose of this content?
Only then, verify that screen readers are reading out the information in a correct manner. a>img is a link graphic; JAWS is correct.
Ryan's Notes
There are two ways to maybe get it like that:
Make sure the user is in expert mode with specific settings. Asking a user to adjust their settings so your site reads nicer, probably won't happen.
Write a JAWS script to interpret <a><img> a certain way. _See #1, _
Wrap your text with invisible content markup and hide img-tag from JAWS via aria-hidden:
<a href="#">
<div style="font-size: 0; line-height: 0;">JAWS reads this text</div>
<img src="sample.jpg" alt="sample" aria-hidden="true">
</a>
More ways to create invisible content can be found here:
https://webaim.org/techniques/css/invisiblecontent/
Related
I have be rewriting my website to be accessibility friendly and have a really good handle on good behavior, but I'm having a problem with the following pattern:
I have a list page of blog entries that I am trying to remove a duplicate link alert for (I know it's just an alert, but it's right to alert me).
<article>
<a href="destination">
<img src="decorative picture.jpg" alt="">
<h2>Blog entry title</h2>
</a>
<p>Summary of blog post and other meta info about the post</p>
<p>
<a href="destination" class="btn btn-details" tabindex="-1"
aria-label="Continue reading about Blog Entry Title">
Continue reading
</a>
</p>
</article>
The usual pattern discussed is when you have an image and title together (solved), but what should I do with the "continue reading" part? It is not, nor should it be, near the image/title, but it really is redundant. I thought about either making the link or the surrounding paragraph aria-hidden="true" because "Continue reading" is really stylistic, someone in a screen reader would know to click the link above, but I know we're not supposed to put links in a hidden context. I thought tabindex="-1" would solve that problem, but there is still a link there, it's just not focusable and is weird for visual navigators because they can't tab to it.
I found the following article, which makes me wonder if I should remove tabindex and use aria-labeledby to bring some semantic connection to the previous link?
<article>
<a id="md5-hash-of-destination" href="destination">
<img src="decorative picture.jpg" alt="">
<h2>Blog entry title</h2>
</a>
<p>Summary of blog post and other meta info about the post</p>
<p>
<a aria-labeledby="md5-hash-of-destination" href="destination"
class="btn btn-details">
Continue reading
</a>
</p>
</article>
What is the optimal way to "eliminate" the entire Continue reading link to give the best UX to people who use screen readers et al?
I think the key to your question is at the very end where you're asking about the UX since the code you have is technically accessible according to WCAG.
Having two adjacent links go to the same destination isn't ideal but it's not a horrible UX either. Users with mobility issues will have two tab stops to navigate through for each article, which can be draining for some assistive technology such as a sip-and-puff device.
I'm not sure I see the need for the "continue reading" link at all. Hearing the blog title and that it's a link, then a summary afterwards seems sufficient. What benefit is the "continue reading" link? I suppose my question might be better asked on https://ux.stackexchange.com/.
If you have to keep the second link for whatever reason, you definitely don't want tabindex="-1" on the link. That would give you a link that mouse users can click on but keyboard users couldn't. Technically, that's not a failure of WCAG 2.1.1 since that guideline says that all functionality of the page must be available to keyboard users, and since your first link is available, having the second link unavailable doesn't fail.
But if you shouldn't have tabindex="-1" on the link, then you shouldn't have aria-hidden="true" either. As you said, interactive elements should not be aria-hidden.
If you really want to keep the second link, my first choice is just leave it as is. If you only want one link clickable, then perhaps make the entire <article> a link. That would cause the blog title and the blog summary/metadata and the "continue reading" to all be read as the link name. That makes for a pretty wordy link, which isn't a great UX either.
So I'm not sure you have a win-win situation. My first choice is to remove the second link completely. The "continue reading" doesn't seem to have any benefit.
Your second code example is not much different from your first. You changed the label of the second link so it ends up being less accessible than your original code. You'll hear "blog entry title" as the name of both links. The "continue reading" will not be announced because you're overriding the link text with the aria-labelledby.
I need to have a screen in my app which all of it's content will be read using the screen reader automatically.
I tried to add role="dialog" aria-live="assertive" aria-atomic="true" and it didn't make it.
I also tried to use role="alert" aria-live="assertive" aria-atomic="true" it did read it, but using 'alert' as prefix.
How can I make it happened using no prefixes and additional info ?
I believe the document role is the correct one to use in your case. From MDN:
Generally used in complex composite widgets or applications, the document role can inform assistive technologies to switch context to a reading mode: The document role tells assistive technologies with reading or browse modes to use the document mode to read the content contained within this element.
You should include tabindex="0" on the element in which you wish to be immediately read, and use JavaScript to set the focus to the element.
Update
I tested the following code in Mac/Chrome, version 79.0.3945.88, and removed the tabindex attribute as well as all JavaScript. VoiceOver immediately read the contents of the document in its natural order.
<div class="container" role="document">
<p>
Read this first.
</p>
<p>
Read this next.
</p>
</div>
I did a screen capture of the VoiceOver utility as it was reading the above HTML to show it working on page load (forgive the Giphy Capture bit at the beginning of the gif).
If this really is something like a dialog - which means it consists mostly of operable content (UI controls such as buttons) then the non-operable content will not get announced by default. You can solve this if, on the thing with role="dialog", you have aria-labelledby pointing at its heading, and aria-describedby pointing at all the ids (space-separated) of the elements inside that you want read-out when it opens.
The markup might look like this:
<div role="dialog" aria-labelledby="dialogheading" aria-describedby="foo bar">
<h2 id="dialogheading">Let's have a dialog</h2>
<p id="foo">lorem ipsum</p>
<p id="bar">rhubarb rhubarb</p>
<button>yadda</button>
<button>yoda</button>
</div>
If there's really a lot of non-operable content, or if there's no operable content, role dialog is the wrong thing. If the context for this 'screen' is in forms/application mode use role=document instead, and make sure it has a tabindex so you can give it focus, which should switch the screen reader to browse mode.
This question is about Accessibility.
Here is my code:
<a href="https://example.com/url-to-details">
<img src="https://example.com/item.png" alt="some description">
</a>
some description
It's not perfect, as we know we should avoid Adjacent links go to the same URL (this is what the WAVE accessibility tool says for me on my webpage about this piece of code).
With another words, the problem here is you use th Tab key consequently and still appear on the same link. This is not perfect.
My solution is to set tabindex="-1" for one of the links.
So, my questions are:
1. is it a good idea, or you have a better approach?
2. Which code is better from the Accessibility point of view:
<a href="https://example.com/url-to-details" tabindex="-1">
<img src="https://example.com/item.png" alt="some description">
</a>
some description
or
<a href="https://example.com/url-to-details">
<img src="https://example.com/item.png" alt="some description">
</a>
some description
P.S. There is a 3rd approach: to unite two <a></a><a></a> into one such as <a> picture + some description</a>, but I would avoid it for some reasons.
P.P.S. The description text "some description" is equal for both the image description and the text in the anchor tag.
I don't see a use case for having both an image link and an adjacent textual link that use the same URL. It should be a single link, so you have three options:
get rid of the image link,
get rid of the textual link,
combine the image and the text into a single link, where the image has an empty alt attribute:
<img src="https://example.com/item.png" alt=""> some description
In the third case, the alt attribute should be empty in order to avoid duplication of text (screen reader users don't want to hear the link text twice). This also results in simpler code that does not rely on tabindex="-1". See also WCAG Technique H2: Combining adjacent image and text links for the same resource.
Note that using two adjacent links, both with the href attribute and one of them having tabindex=-1, as proposed in the question, will result in both links being listed in a screen reader's list of links. This duplication should be avoided.
Assuming that your alt description should be equal to your link text is a misguided approach, in my opinion.
Let's say you are designing a products list page for an online store.
If the link goes to a product detail page, then the link text should describe that detail page. However, the image alt should describe the image itself, not the detail page.
.link {
display: flex;
flex-direction: column;
align-items: center;
}
<a class="link" href="https://www.mywebsite.org/detail-page-100">
<img class="link-img" src="https://picsum.photos/200" alt="2 puppies running through a meadow in the summer sun">
<span class="link-desc">Buy organic pet food - 5kg</span>
</a>
The tabindex only changes the keyboard order, but screen reader will still announce the same link twice.
Making the img clickable using javascript will avoid annoying keyboard users or screenreader users, letting mouse users click on the image itself.
From a purely WCAG accessibility point of view, nothing has to change in the original code. That fact that WAVE points it out is just an artifact of that tool. It's not an error, but an "alert" (in WAVE terms). The doc for WAVE says this about "alerts":
The goal should not be to get rid of all icons, except for the errors. Alerts will require close scrutiny - the[y] likely represent an end user issue.
The key being that alerts are "end user" issues, meaning usability or user experience issues. Not accessibility failures.
So, if you're trying to comply to WCAG AA, having a redundant link is not a failure and does not have to be fixed. But if you're looking at the user experience, reducing the number of tab stops and links that point to the same destination is always a good thing.
How you fix that issue seems to be the crux of the OP. When two links that are adjacent point to the same location, the best way is to combine the links into one. Adding tabindex="-1" to one is generally a bad idea because that only affects keyboard users and not screen reader users.
I would keep them both, because if a person using a screen reader is tabbing through your website you would like them to hear the image description as well as the text in the anchor tag.
The correct answer is - it depends.
If your image better describes your link, then use the image.
If your anchor tag better describes it - then use the <a>.
Some info for tabindex
Please see all the accessibility you can add to a link here
I'm working on fixing some accessibility issues on a web page. I have this div that acts as a dialog, and inside at one point a div containing a loading animation and a text "Working..." is displayed.
I am unsure as to how to label these two items in order to correctly notify the blind user that there is a progress animation and that it's working and he should wait.
<div id="loading" style="display: none;">
<div class="mgBot15"><span class="txt16" role="alert">Working...</span></div>
<img src="loading.png" role="progressbar" aria-busy="true"/>
</div>
I tried adding the role and aria-busy properties to the img (also to the parent div, at first).
When this div appears (by changing the display style property), it correctly reads "Working..." but I hear no indication that it's busy and that the user should wait, am I missing something?
I've looked all over for examples for loading animations, to no avail so far.
Note: I'm using NVDA as a screenreader to test.
Thanks
The best solution I could come up with was using role alert, and aria-busy="true".
<div id="loading" style="display: none;">
<div class="mgBot15"><span class="txt16" role="alert" aria-busy="true">Working...</span></div>
<img src="loading.png" alt="loading" />
</div>
I believe the most sensible approach would to use the combo
aria-busy="true" aria-live="polite"
The reason for that is because some pages might have a lot of separate loaders (let's say one for each component, not a single loader for the whole page) and it you use aria-live="assertive" or role="alert" it will be very intrusive and each of the loaders will get called out.
The correct role to use here is progressbar as the original question used. Other roles like alert may work, but they are less specific, meaning assistive technology may present the information in a less ideal manner.
There are a few issue with the original question's example, though:
If you wish to have the text be announced in the same as an alert is, aria-live="assertive" should be used rather than the alert role. That aria-live value is what causes the screenreader to announce the text when it does for an alert.
The text to be announced should be set on the element with the progressbar role using the aria-valuetext attribute. It should not be set solely on a separate adjacent element. If it needs to also be included in another element for presentational reasons, that element should have aria-hidden="true".
Per the spec, aria-valuemin and aria-valuemax are to be specified even when the progress is indeterminate (like a spinning loading indicator). These could be set to 0 and 100 respectively as simple placeholders implying a percentage.
When the loading is complete, the aria-valuenow could be set to whatever was used for aria-valuemax, and aria-busy can be set to false.
This leads to one potential alternative to the original question:
<div id="loading" role="progressbar" aria-valuetext="Working…" aria-busy="true"
aria-live="assertive" aria-valuemin="0" aria-valuemax="100">
<div class="mgBot15" aria-hidden="true"><span class="txt16">Working...</span></div>
<img src="loading.png" alt="" />
</div>
After a day of fiddling with a similar issue, I was able to finally get this working with a lot of reading and experimenting. I'm using NVDA for a screen reader.
<div class="loader" show.bind="isLoading" role="alert" aria-label="Loading"></div>
The following attributes were key: role and aria-label.
Above example makes NVDA announce "Loading alert" once isLoading becomes true. Important to note is that NVDA pronounces the aria-label value, followed by "alert". Using roles "log" or "status" did not end up in any announcement.
Bootstrap used role="status" like this :
<div class="spinner-grow text-primary" role="status">
<span class="sr-only">Loading...</span>
</div>
and in MDN it said :
The status role is a type of live region and a container whose content
is advisory information for the user that is not important enough to
justify an alert, and is often presented as a status bar. When the
role is added to an element, the browser will send out an accessible
status event to assistive technology products which can then notify
the user about it.
There's a good article I came across that explains what needs to be done for this scenario Loading spinner accessibility
The spinner should be included inside the container. Its visibility can be toggled in relation to the aria-busy attribute. They should always be opposites, i.e, if currently loading, section[aria-busy="true"], .tn-spinner[aria-hidden="false"], once the content is loaded, toggle to false and true respectively.
I am getting H2 violation for below anchor tags.
It says 'H2: Combining adjacent image and text links for the same resource'
<div class="selected-label ccyImage">
</div>
<a href="javascript:void(0);" class="btn dropdown-html-toggle" tabindex="-1">
<span class="caret"></span>
</a>
But there is no any image used. Not getting how to resolve it.
So you have some unspecified tool which is detecting an accessibility problem which is different to the accessibility problem you actually have (or it is being really smart and noticing that you are expressing content using background images … don't do that).
There's not much you can do about the misidentification of the problem other than to report a bug to whomever makes the tool.
You can make your HTML more accessible by:
Not using links when you aren't linking somewhere. If you're using href="javascript:void(0);" then you're doing something wrong.
Link to somewhere useful and progressively enhance or
Use a button (not a link) if you can't make it work without JS
Putting content in your links (or buttons). There is no text at all there to give any clue to the user what the interactive element is going to do.