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