Modal

How the Modal works with a keyboard and assistive tech, and where it stands against WCAG 2.2 AA.

FreeReact and VueModal blocks6 blocksPro
AAWCAG 2.2 target
8/8contrast pairs passing
5keyboard interactions

The Modal is a native <dialog> opened with showModal(). The browser makes everything behind it inert, moves focus inside and returns it to the opener on close, which is most of the WAI-ARIA dialog pattern for free. The component names the dialog by its title, describes it by its copy, and closes on Escape, the close button or a click on the overlay.

Keyboard#

Tab

Moves to the next control inside the modal. The page behind is inert, so focus never lands there.

Shift+Tab

Moves to the previous control inside the modal.

Esc

Closes the modal. Focus returns to the control that opened it.

Enter

Activates the focused button.

Space

Activates the focused button, or ticks the footer checkbox or toggle.

Semantics#

<dialog>

Opened with showModal(), which gives it the dialog role, makes it modal and the rest of the page inert.

Open
aria-labelledby

Points at the title (an <h2>), so the dialog is announced by name when it opens.

Always
aria-describedby

Points at the status copy or the header description.

Has a description
role="alertdialog"

For a status modal that asks people to confirm something irreversible, set it on the <dialog> so it is announced as urgent.

Destructive confirmation
<button aria-label="Close">

The 24px close button in the header. A Status Modal has none; Escape and Cancel close it.

Header close
aria-hidden="true"

The icon is decorative. The title says Error, Warning or Success in words.

Status icon

Colour contrast#

Every variant and state has to meet WCAG 2.2 Level AA. Measure the colours as they land on screen: a translucent hover or press wash over whatever sits behind it.

4.5:1

Title and copy · Always

The title is #2a2a2a on white (14.35:1); the description and body #6d6d6d (5.17:1).

WCAG 1.4.3 Contrast (Minimum) ↗
4.5:1

Footer buttons · Rest, Hover

12px Cancel and Continue labels against their fills. Continue is white on brand blue; Cancel is #6d6d6d on white with a #e1e1e1 edge.

WCAG 1.4.3 Contrast (Minimum) ↗
3:1 if needed

Status icon · Status Modal

The glyph on its tint: Error 3.60:1, Warning 2.02:1, Success 3.37:1, Information 4.81:1. Warning falls short, which is acceptable only because the title states the status.

WCAG 1.4.11 Non-text Contrast ↗WCAG 1.4.1 Use of Color ↗
3:1

Focus indicator · Focus visible

A 2px #1a6ef8 ring off a 2px white gap on every control (4.54:1). The modal is centred and capped to the screen, so the focused control is never hidden behind it.

WCAG 1.4.11 Non-text Contrast ↗WCAG 2.4.13 Focus Appearance ↗WCAG 2.4.11 Focus Not Obscured ↗
No trap

Keyboard containment · Open

Focus stays inside while the modal is open, and Escape always closes it. Tab can still reach the browser's own controls, which is expected.

WCAG 2.1.2 No Keyboard Trap ↗WCAG 2.4.3 Focus Order ↗

Measured contrast#

Footer labels and the header's close glyph against their fills, at rest and on hover, on the modal's white surface. All 8 pairs reach their minimum.

PartRestHover
Footer · Cancel5.17passes4.62passes
Footer · Continue5.40passes8.53passes
Footer · Link5.17passes14.35passes
Header · Close glyph14.35passes13.17passes

Motion#

  • The surface rises 6px and fades in over 200ms, and the overlay fades over 160ms, only when motion is allowed.
  • Under prefers-reduced-motion it appears at once. The overlay's blur is static.

Checklist#

Every modal has a visible title wired to aria-labelledby. A modal with no title needs an aria-label.

For a destructive confirmation, put initial focus on the least destructive control (Cancel), using autofocus.

Overlay clicks close the modal. For a form that would lose typed data, confirm before closing, or turn that off.

The header close button is 24px, exactly the target minimum. Footer buttons are 40px.

Keep the body short. Anything long or worth linking to belongs on a page.

The Warning status icon is below 3:1 on its tint; the title must always say what happened.