Reading the ARIA Authoring Practices Guide
How APG is structured, when to follow it, and when to deviate.
You'll see the ARIA Authoring Practices Guide referenced everywhere accessibility is discussed — usually shortened to APG. It lives at https://www.w3.org/WAI/ARIA/apg/, it's maintained by the W3C, and it's the most useful reference for "how do I build a [combobox / tree / dialog] with ARIA" you'll find.
It's also a guide, not a spec. Treat it as expert advice with limits — sometimes excellent, sometimes outdated, occasionally controversial within the accessibility community itself. This lesson teaches you how to read it well.
What APG is — and isn't
APG is a collection of patterns with example code and keyboard contracts for the common interactive widgets: tabs, dialogs, comboboxes, menus, trees, grids, accordions, carousels, and more. Each pattern was authored to demonstrate that this particular ARIA recipe works in major screen readers.
What APG is not:
- Not the ARIA spec. That's a separate W3C document (
wai-aria-1.2) defining what each role and attribute means. APG shows you how to use the spec for specific UIs. - Not the only correct answer. Some patterns are debated. The "menu" pattern in particular has well-known criticisms: it's modeled on desktop menus and often hurts users on web pages, where users expect different behavior. A pattern in APG is a reasonable starting point, not a verdict.
- Not a substitute for testing. APG examples have been tested with several screen reader / browser combinations, but your version of the pattern — with your styling, your data, your edge cases — needs its own testing.
When you Google "ARIA combobox example," the first result is often APG. That's a good place to land. It is not a good place to stop.
How a pattern is structured
Every APG pattern page follows roughly the same outline. Once you know the shape, you can scan a page in under a minute:
- About this pattern — a paragraph or two explaining what kind of UI this is. Read this. If your widget doesn't match the description, you're on the wrong page.
- Examples — usually two or three live demos with full source. The demos are runnable; play with them with the keyboard and a screen reader, not just your eyes.
- Keyboard interaction — a table mapping keystrokes to behavior. This is the contract. If you can't deliver every row in this table, you're shipping a worse version of the pattern than APG describes.
- WAI-ARIA roles, states, and properties — the attributes the example uses, with required and optional ones called out. This is where you'll find which
aria-*attributes belong on which elements. - Notes / accessibility considerations — tradeoffs and known issues. Often the most useful section.
If you skip section 3 (keyboard) you will ship a broken widget. Almost every "this is inaccessible" complaint about a custom widget on the web traces back to that table being half-implemented.
Mapping a design to a pattern
Designers don't think in ARIA patterns; they think in UI ideas. Translating a mockup into the right APG page is a skill. A few rules of thumb:
- A button that opens a panel that disappears when you click anywhere → "Disclosure" pattern.
- A button that opens a panel modally (focus is trapped, you must close it explicitly) → "Dialog" pattern.
- A row of titles where one is highlighted and shows content below → "Tabs" pattern (mutually exclusive) or "Disclosure" (if independent).
- A textbox with a popup of suggestions → "Combobox" pattern.
- A row of icons that act like a menu bar → likely a
role="toolbar", not a menu. - A floating menu of actions opened by clicking a "..." button → debatable. Often better as a popover with regular
<button>items than asrole="menu"(see APG's caveats). - A row of items where exactly one can be selected → "Listbox" or radio group.
When two patterns seem to fit, prefer the simpler one. Disclosure beats tabs. Buttons beat menus. Native <select> beats listbox. Every layer of "this is more like a real desktop app" you add is more keyboard contract you have to maintain.
When to deviate
You will sometimes find an APG pattern that doesn't quite fit. A few principles for deviating:
- Test the deviation with real assistive tech. APG patterns were tested with NVDA, JAWS, VoiceOver. Your variation is not. Spend twenty minutes with each.
- Document why you deviated. A comment in code, a note in your design system: "Used button + popover instead of role='menu' because users on /[page] expected
<a>-style links inside." Future maintainers need to know. - Watch for community pushback. The APG menu and carousel patterns have been criticized as "too desktop." If you find yourself with a working alternative, it may already be the more accessible choice.
- Don't deviate to make less work. Skipping arrow-key navigation in a tablist saves 30 lines of code and breaks the widget for keyboard users.
Deviating downward — fewer keyboard keys, weaker announcements, simpler ARIA — is almost always wrong. Deviating sideways — different pattern entirely (popover instead of menu) — is sometimes right.
Where to go from here
You now have the working ARIA vocabulary: roles, states, properties, accessible names, live regions, hiding, the canonical patterns, and the composite ones. The next courses go deeper into application:
- Accessible forms and dynamic UI — labels, error messages, multi-step flows, and the trickier validation patterns.
- Accessibility testing and process — automated testing, screen reader testing, and how to make accessibility part of code review rather than a launch-week panic.
The single most useful thing you can do this week is open NVDA (free, on Windows) or VoiceOver (built-in, on macOS) and tab through your own product with eyes closed. Whatever surprises you is your next project.