Is aria role="alert" announced on page load? - html

Will content with role="alert" be announced by screen readers on page load?
I have seen contradicting advise from MDN on this.
https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/Alert_Role states:
[T]he alert role is that it is for dynamic content ... if a page loads with multiple visible alerts scattered throughout, none would be read because they are not dynamically triggered.
While another page states it can be used with static content:
Example 1: Adding the role in the HTML code
The snippet below shows how the alert role is added directly into the html source code. The moment the element finishes loading the screen reader should be notified of the alert. If the element was already in the original source code when the page loaded, the screen reader will announce the error immediately after announcing the page title.
Can/should the alert role be used on static content or only for live regions?

I've found that it isn't reliably read out. Some screenreaders do read out the alert, but others don't. We've partially got round this issue by also moving focus to the element with role="alert" on, as that's also often a trigger for reading an element out. It also makes sense that if a page reloads and a message is read out, the user will expect their focus to be on that message.
This codepen is quite useful in showing the impact of using role=alert in different ways: codepen.io/vloux/full/JOwxmO
There is a discussion in the aria Github repo about adding a new property that reads on page load. Whether or not this is done (there is some disagreement), there is definitely a gap on what the behaviour should be and this needs to be defined.

Related

Make text tab-able for screen reader

I have some text that displays if there is an error
<div>Error message</div>
When the error div is displayed I want the user to be able to tab with their keyboard over this so it can be read by a screen reader so it is accessible for everybody.
While there is a simple way to accomplish this, it is not how screen reader users would expect an error message to be used: Expectation is to have the error when focussing the input element itself.
Screen reader support is not rendering content accessible to everybody. There are plenty different kinds of disabilities, and only some users benefit from screen readers. For others, other techniques are necessary.
For example, colour contrasts and a layout that does not break when font size is increased helps users with visual impairments, and keyboard focus needs to be visible for those who can see but navigate by means of keyboard.
As a start, I recommend the W3C’s Stories of Web Users in How People with Disabilities Use the Web to get an idea. The other articles and videos on that site are very well done, as well.
The foundation for any accessibility technique is to properly structure HTML, use headlines and landmarks for orientation, and use semantic tags instead of generic <div>.
How screen reader users navigate
There are several ways to navigate a document/a page with a screen reader, depending on current use case:
Simply read all elements on the page (including text)
Read the next/previous block of content
Navigate to a heading via a list of headings
Navigate to a landmark/form from a list of landmarks
Navigate to a link via a list of links
Navigate to the next/previous interactive element by means of tab
Aspects to render an error message helpful to screen readers
It should never be necessary for a (screen reader) user navigate/explore the site to see whether there was an error. The error should be announced immediately after the intended interaction.
How to achieve this, depends on how you are running form validation. Inline, server- or client side. Web AIM have a great article on Usable and Accessible Form Validation and Error Recovery.
For example, if your error message is related to an input field, and you have client-side validation, it is very important to establish the relationship between them, which is often achieved by means of aria-describedby.
<label>Name
<input type="text" name="name" autocomplete="name" aria-invalid="true" aria-describedby="name-err">
</label>
<div id="name-err">Please provide a name</div>
If validation is run on Submit, a best practice is to set focus to the first input in error via JavaScript .focus().
How to make any element tab-able
The tabindex attribute will render any element reachable by means of tab. You should not set it to a positive value.
<div tabindex="0">Error message</div>
If you want an element to receive focus only programmatically by means of JavaScript (on submit, for example), but not by means of tab, you can use tabindex="-1".

ARIA Live Regions for single page applications

I am new to accessibility of web pages. I have an application where the content of the body changes based on the header link clicks in an ajax call without page refresh. So the HTML content inside the body gets updated for each link click with different page content (table + button + information text).
My requirement here is the screen reader should announce the information text each time when the page gets loaded. Here the container is body (or an immediate div inside body) for all pages. So I have made it aria-live="polite", but every time page loads it is announcing the whole page content but I want to make it announce only the information text. Other elements of the page should be announced on focus/visit. I hope I can apply aria-live="off" for all other elements but I'm looking for any ideal solution for this. I cannot change the layout of the application.
Can some one help me on this. Thanks in advance.
SPA pattern best practices
You are essentially following a Single Page Application pattern. As such the method recommended for handling navigation is actually quite straight forward with two steps.
tell a user that navigation is about to occur (before navigation)
let a user know that loading is complete (after navigation).
before navigation (link click)
You need to signal to a user that a page is loading if you are using a SPA pattern (and therefore interrupting normal navigation). e.g. I click your link, you need to let me know that an action is being performed (loading.....) as you intercept the normal browser behaviour with e.preventDefault() or equivalent.
The simplest way is to use aria-live=assertive on a region that explains the page is loading. You can Google how to implement that correctly but essentially you would update the content of a hidden div (<div aria-live="assertive" class="visually-hidden">loading</div> with some loading message the second a link is clicked.
This should be done before any AJAX calls are made.
after navigation (new content loaded)
When the new page loads you need to manage focus.
The best way to do this is to add a level 1 heading (<h1>) to each page that has tabindex="-1". By using tabindex="-1" it means that the heading won't be focusable by anything other than your JavaScript so won't interfere with the normal document flow.
Once the page loads and the content has been populated fully the last action you perform in your JavaScript navigation function is to place the focus onto this heading.
This has two benefits:
it lets the user know where they are now
it also lets them know when the page load is complete (as AJAX navigation doesn't announce when the page is loaded in most screen readers).
At this point you may also want to clear the <div aria-live="assertive"> contents so that it is ready for further navigation.
Have you tried to wrap the "live zones" - where updates happen in div with aria-live="polite". Then screen reader will announces only these zones on updates.Don't wrap whole page or div in aria-live="polite".
<div aria-live="polite">
<p id="errorText">Announced on update</p>
</div>
<div>
other page sections..
</div>

Does preventing a modal from being hidden by clicking the background violate accessibility requirements?

I'm adding a blocking modal (ie one that covers the screen and prevents interaction while an API call is processing) to my company's design library.
As part of that, I modified our modal so that clicking on the grey backdrop will NOT hide the blocking modal, but I want to make sure that doesn't violate accessibility guidelines. I haven't been able to find anything online about this. Does anyone know if this this violates accessibility requirements?
Short Answer
The answer is 'it depends'. Basically if the modal is not dismissable in any way it becomes a 'keyboard trap' and so would violate WCAG.
However if you structure it correctly a modal that blocks the page while an API loads is perfectly valid (and can't be dismissed while the page is loading), but there are a few things you need to do to make sure this is accessible.
1. Make sure that when this modal loads, nothing else on the page is focusable.
The biggest issue I see on most modals is that they allow focus outside of them.
You can't just stop users using the tab key as that is not how most screen reader users navigate the page (they use shortcuts for headings (h1-h6), hyperlinks etc.).
For this reason make sure your modal sits outside of your <main> and the hide your <main> and other major landmarks that contain information with aria-hidden="true" and by adding tabindex="-1" to them so nothing is focusable.
Obviously this depends on your document structure so you would need to test it, but a properly structured HTML document will work with the above method.
2. Make sure that a screen reader user knows that the page is busy and something is loading.
There are a couple of ways to do this. The best is to use an aria-live region
Adding aria-live="polite" and aria-busy="true" to the section you are updating is one way (if you are updating one part of the page).
However in your circumstances I would make a section within the modal aria-live="assertive" and not use the aria-busy (as you will be hiding all the content in step 1 so aria-busy would not be applicable).
I would then update the message every second or two for long loads (i.e. 'loading', 'still loading', 'nearly loaded' etc. Or better yet a loading percentage if your script allows.)
Once the page content has loaded, you do not need to say 'loaded' instead make sure you have a heading for the section or page that has a tabindex="-1" added on it that accurately describes the content that has just been loaded in.
Once the load completes, programatically focus this heading and the user will know that the load is complete.
3. Make sure that if the API call fails you feed something meaningful back to screen readers
When your API call fails (notice I said when, not if!) make sure your JavaScript can handle this in a graceful way.
Provide a meaningful message within your modal aria-live region that explains the problem. Try to avoid stating error codes (or keep them short, nothing worse than hearing a 16 digit string on a screen reader for an error code), but instead keep it simple such as 'resource busy, try again later' or 'no data received, please try again' etc.
Within that region I would also add one or two buttons that allow to retry / go back / navigate to a new page depending on what is appropriate for your needs.
4. For long load times, let the user know what is happening.
I covered this in point 2 but just to emphasise it, make sure you feedback to users that things are still loading if there is a long load time by updating your aria-live region.
Nothing worse that wondering if the page has loaded and the developers forgot to tell you.
5. Give the option to cancel an API call so it doesn't become a keyboard trap.
Obviously the big problem with a whole page modal is it is a 'keyboard trap'.
To ensure this isn't an issue make sure you provide a cancel button.
Make sure it is clear that this will cancel the loading of the page, but don't rely on JavaScript alone.
Instead make this a <a> styled like a button that either points to the current page or the previous page (yet again depending on your needs) and add role="button".
Then intercept this click with JavaScript so that it can function like a button.
The reason for this is that when your JavaScript fails (yet again - when, not if) the user still has a way to get to a meaningful page, thus avoiding a keyboard trap.
This is one of the few times you should use an anchor as a button, as a fallback!
By doing this you ensure that the user always has a way to escape the modal.
You may also consider allowing a user to use the Esc key to close / cancel but that is yet again down to you and your circumstances.

Accessibility: what's the way to force reading of span text on page load

I'm curious what's the proper way to push the screen read to read <span>read me on load</span> first (it's in the middle of the html page) when the page is loaded?
Even
role="rude"
doesn't help for some reason.
Thank you.
What you are using is not part of ARIA live regions. You want either role=alert or aria-live=assertive (though in an early draft "assertive" was originally "rude").
Now, that being said, live regions are intended for use on an already-loaded page. If you are making a dialog, then your HTML might look like this:
<div role="alert" aria-live="assertive">
Anything in here will be announced as soon as it changes.
</div>
If you want the dialog to be announced at page load, then consider hiding its contents and then using script to display its contents once the page has finished loading.
If you need to make it announce as soon as the page loads and it is not a dialog, consider moving focus to the element at page load using script. By placing focus, the browser will announce whatever it is.
For this to work, however, you cannot just place focus on a <span> as it is not interactive content. You can make it interactive by adding a tabindex attribute. If you do that, then you will need to add a role describing what the element does (you can use role=region if you are stuck) so that the screen reader can announce what it is instead making the user think she has landed on a control or otherwise expect to be able to take an action.
If you are moving focus to the element for users without screen readers, or if the very first thing the page displays at page load is an alert of some sort, then this should be fine.
However, since you have provided no context and no examples, and given all the ways this can be done that are far worse than doing nothing, please ask yourself this:
Is the thing you want to announce…
…an alert or dialog?
…a control that already can receive keyboard focus?
…going to be given focus for all users, not just those with screen readers?
If you end up saying no twice then you should not do this.
If you can provide an example URL that shows what you want to do, then I am happy to help you get it working. Otherwise I fear you may be coding something that ends up creating a trap or barrier for screen reader users.

Changing form to include a submit button for WCAG

I currently have a form like so:
<form action="#">
<select {if $isPostRequest}disabled="disabled" {/if}size="1" name="locale"
onchange="location.href={if $languageToggleNoUser}'{$currentUrl|escape}{if strstr($currentUrl, '?')}&{else}?{/if}setLocale='+this.options[this.selectedIndex].value{else}('{url|escape:"javascript" page="user" op="setLocale" path="NEW_LOCALE" source=$smarty.server.REQUEST_URI}'.replace('NEW_LOCALE', this.options[this.selectedIndex].value)){/if}" class="selectMenu">{html_options options=$languageToggleLocales selected=$currentLocale}</select>
</form>
It currently causes a WCAG 2.0 error, as all forms need a submit button.
I'm wondering how I could change this code to include a submit button. The code for the onchange option is quite convoluted, and I don't understand it.
Thanks.
WCAG 2.0 does not require to have a submit button. What you link to is a technique, which is informative (not normative), and it’s only one of possibly many ways to achieve the guideline 3.2.2.
So it can be conforming to have no submit button, for example when
the user has been advised of the behavior before using the component
Related technique: G13: Describing what will happen before a change to a form control that causes a change of context to occur is made
The important thing to note here is that a change of content does not immediately mean a change of context.
From a 3.2.2 guideline perspective, your select box is highly likely to be perfectly fine.
A change of context means a really drastic change. Something like when the user selects an option in the select box, focus is shifted to a different section of the page. Also things like causing a full page refresh or opening a new tab will also fail this criterion.
WCAG "change of context" definition
major changes in the content of the Web page that, if made without user awareness, can disorient users who are not able to view the entire page simultaneously
Changes in context include changes of:
user agent;
viewport;
focus;
content that changes the meaning of the Web page.
Note: A change of content is not always a change of context. Changes in content, such as an expanding outline, dynamic menu, or a tab control do not necessarily change the context, unless they also change one of the above (e.g., focus).
Example: Opening a new window, moving focus to a different component, going to a new page (including anything that would look to a user as if they had moved to a new page) or significantly re-arranging the content of a page are examples of changes of context.
So if all you are doing is modifying some content elsewhere on the page and not messing around with the users focus point, you are doing everything just fine from a 3.2.2 guideline perspective.
You are currently failing in another way though
There is one thing that is causing your select box to fail accessibility. It is lacking a label. This is a fail against guideline 2.4.6 Headings and Labels. The lack of a label means that users will not know what the select box is for.
<form action="#">
<label for="unique-id">Label for select box</label>
<select id="unique-id" {... all that other junk ...}>
{...<option> elements...}
</select>
</form>