How To Build An Accessible Modal
Modal window (or dialog box) is one of those classic element composing an interface. Every app or website has a modal. But it’s surprisingly hard to get it right.
Accessibility Concerns About Modals
I used to think that building a modal in React is just a matter of showing a box when a variable is set to true (after a click on a button for example). But there are many things, accessibility related, to consider :
- annonce the modal and hide the rest of the page from screen reader
- make the first element tab-able inside the modal to have focus
- close the modal when clicking outside or when pressing esc key
- restore focus after closing the modal
Using Headless Modal Component
You could try to implement a modal from scratch. But I strongly advise you against that (at least for production code).
In React, there are many headless component libraries that help developers build accessible interfaces. Headless components are a type of unstyled components that are fully functional.
You can find below few examples of headless modal libraries
- react modal (most popular)
- reach UI dialog (what I recommand)
- radix UI dialog
- reakit dialog
React modal is clearly the most popular out there. But I think it is not the best option, because you can disable some accessibility features needed for a modal.
For the other libraries, important accessibility features are enabled by default. Each of them is a good solution but I have a preference for Reach UI dialog for its ease of use (simple API and component easily style-able).
Reach UI Dialog Quickstart
Installation
Implementation
In this example, I use Stitches. But you can use any CSS-in-JS library of your choice. You can also use CSS modules to style DialogOverlay and DialogContent
Usage
What About The Official dialog Element ?
Although major browsers support it recently, there are still accessibility issues that are being discussed. I think, reaching for a solution like headless components is totally valid for now.