Lesson 10 of 30
An accessible modal isn't one property to set — it's a checklist of five distinct requirements, and the most common production bug is getting the visual overlay right while quietly shipping only two or three of the five.
14 min read
Every option explains itself — why the right one is right, and why each wrong one is wrong. Miss one and it comes back later on a spaced-repetition schedule.
Question 1 of 3
A modal has correct focus trapping and Escape-to-close, but the rest of the page is not marked `aria-hidden` or `inert` while it's open. What's the actual consequence?
Hints without spoilers, and a plain explanation of why a wrong answer was wrong — answered only from this lesson. Free account, no card.
Sign up freeWhat interviewers actually ask about this, and what a strong answer has to cover.
A strong answer covers
Likely follow-ups
A modal dialog is probably the single most commonly half-implemented accessible pattern in real production code. Teams reliably get the visual part right — a centered box, a dimmed backdrop, a close button — and just as reliably ship it with broken keyboard and screen reader behavior, because the visual overlay is the part that's obvious from looking at the screen, and the rest isn't.
Here's what "accessible modal" actually requires, end to end. This lesson is a synthesis: it names five requirements, and two of them are full topics covered in earlier lessons in this track — focus management (moving focus in, trapping it, restoring it on close) and the underlying keyboard mechanics behind composite widgets. Nothing about those two gets re-explained here; they're referenced by name and assembled into the complete recipe.
role="dialog" (often paired with aria-modal="true") so a screen reader announces this as a distinct interaction context — not just another chunk of page content that happened to appear.aria-labelledby, pointing at the dialog's own heading, so a screen reader announces what the dialog is, not just that a dialog exists.Escape closes the dialog — a standard, expected keyboard convention. A user who wants out shouldn't have to hunt for a close button with the mouse.aria-hidden="true" (or made genuinely inert via the inert attribute) while the dialog is open, so a screen reader user can't accidentally navigate into background content that's supposed to be unavailable — mirroring what the focus trap already does for keyboard reach.function Modal({ isOpen, onClose, triggerRef, titleId, children }) {
const dialogRef = useRef(null);
useEffect(() => {
if (!isOpen) return;
dialogRef.current?.focus(); // 3. focus moves in
const background = document.getElementById("app-root");
background.setAttribute("inert", ""); // 5. background made inert
function onKeyDown(e) {
if (e.key === "Escape") onClose(); // 4. Escape closes it
// Tab/Shift+Tab trap logic goes here — see the focus-management lesson
}
document.addEventListener("keydown", onKeyDown);
return () => {
background.removeAttribute("inert");
document.removeEventListener("keydown", onKeyDown);
triggerRef.current?.focus(); // 6. focus restored to the trigger
};
}, [isOpen]);
if (!isOpen) return null;
return (
<div
ref={dialogRef}
role="dialog" // 1
aria-modal="true" // 1
aria-labelledby={titleId} // 2
tabIndex={-1}
>
<h2 id={titleId}>Delete this item?</h2>
{children}
</div>
);
}
Before open: a trigger button on the page. Nothing in the checklist is satisfied yet.
Every numbered comment in that snippet maps to one line of the checklist above. None of them is optional polish — drop the inert call and a screen reader user can navigate "into" content that's visually blocked by the backdrop; drop the cleanup's .focus() call and the trigger-restoration behavior from the earlier lesson silently disappears the moment this gets refactored.
aria-hidden on the background needs to happen on open and be reverted on close, every time — a modal that can be opened and closed repeatedly needs this toggled correctly on each cycle, not just set once.inert is the more robust choice over manual aria-hidden toggling where it's supported — it also prevents actual mouse/pointer interaction with background elements, not just screen reader reach, closing a gap aria-hidden alone leaves open."Build me an accessible modal" or "here's a modal — what's missing for accessibility?" is one of the most common practical accessibility exercises in real interviews, precisely because it's the pattern most candidates have implemented visually but never audited end to end — naming all five-plus requirements, not just "add a role and trap focus," is what separates a shallow answer from a strong one.