What's the problem with modals?
I guess the first problem with modals, maybe the most fundamental problem, is that they don't actually work how you'd expect them to.
When defining a modal you need to think about the functionality:
- A modal should open on top of content.
- A modal should capture user focus.
- A modal may have an optional backdrop to fade out content behind.
But then you need to go a step further and think about the use cases of a modal and realise that you've got a few different patterns at play.
Each of these patterns has a unique set of functional requirements, and whilst they share a common set of accessibility requirements, you have to consider each one and their use case.
As no-one seems to have done this right, I know I certainly haven't, W3C have introduced the <dialog>
element. But even that doesn't get you there. Throughout the rest of this experiment I won't be using the <dialog>
element, as it doesn't have great cross browser support, and the Polyfill which the Google Chrome team have developed seems to make matters worse, not better.
Okay, I've painted a pretty bleak picture, but dont lose hope.
Whilst it sounds like all is lost, and by no means will the following fix all defects across this staggering array of devices, it turns out there are a number of things you can do.
- Thankfully both Angular (via the Angular CDK) and React have the ability to portal your components elsewhere in the DOM tree, allowing you to put your modal in a sensible place... the end of the document.
- Again, Frameworks to the rescue, both Angular (via the Angular CDK) and React (via React-Focus-Lock) have the ability to focus lock your modal. If a user tries to escape, they get pulled right back in.
- When your Modal is open, make everything is
aria-hidden="true"
except for your modal, this means that even if the screen reader fails to get focus into your modal, the only place the user can go is into the modal. There's a great package Aria Hidden which can help you with that, and as it's Vanilla.js™ it'll work anywhere you need it. - ALWAYS have a focusable item, it doesnt need to visually look different, but something such as a button, or even a
<span>
withtabindex="-1"
will suffice, and when your modal opens, focus on that item. - If you don't need a user to interact, such as an interstitial, use an
aria-live
region to announce to your users what's going on. - Combine
role="dialog"
andaria-modal="true"
for maximum reachability. - Add
aria-hidden="true"
to the element containing your backdrop, should you have one. - When a modal opens because a user has clicked something, make sure they're returned to the same location.
So if you check out the Examples page, you'll find examples of a few patterns of modals with various functionality included, and the result of cross device testing.