A11y Patterns

DOM Structure Best Practices

Proper DOM structure directly affects screen reader navigation efficiency, focus order, and accessibility tree quality.

Semantic markup

<header>

header / footer / main

Landmark elements allow screen readers to jump between sections using keyboard shortcuts.

<nav>

nav

Navigation link group. Use aria-label to distinguish multiple nav elements.

<article>

article / section

Independent content units and topic divisions. Conveys more meaning than overusing div.

<button>

button vs div

<div onclick> requires manually implementing keyboard access, role, and state. Use native elements.

<ul>/<ol>

ul / ol / li

Use list elements for lists. Screen readers automatically announce item count and current position.

Heading hierarchy

Maintain h1 → h2 → h3 order

Skipping heading levels can cause screen reader users to misunderstand structure. h3 after h1 is prohibited.

One h1 per page

Only one h1 to represent the page topic. Use h2 for sections, h3 for subsections.

Do not skip heading levels

Screen reader users navigate by scanning the heading list to jump directly to a section. Skipping levels makes the page hierarchy feel broken. To change visual size, use CSS — not the heading level.

Nesting depth

Recommended nesting depth ≤ 7–8 levels

Excessive nesting complicates the accessibility tree and makes it harder for screen reader users to understand context.

Minimize layout-only divs

Do not add wrapper divs for layouts solvable with CSS Grid/Flex.

Watch for component abstraction nesting

Many stacked components produce unnecessary divs in the actual DOM. Prefer Fragment.

DOM size

1500

Lighthouse recommends ≤ 1,500 nodes

More DOM nodes increase the cost of building the accessibility tree and slow screen reader initial load time.

Tree

Accessibility tree = subset of DOM

Elements hidden via aria-hidden or display:none are excluded from the accessibility tree, but all visible elements are included.

Virtual

Consider virtualizing long lists

Virtualize hundreds of list items with react-virtual to reduce both DOM size and the accessibility tree.

Focus order

DOM order = focus order

Tab key focus follows DOM order. Even if CSS (e.g. flex-direction: row-reverse) changes the visual order, focus order is still based on the DOM. When visual and tab order diverge, keyboard users become confused.

Never use positive tabindex

tabindex="0" includes the element in the natural tab order; tabindex="-1" makes it focusable only via JavaScript. Positive tabindex values re-sort the entire page's tab order by number, causing focus to jump unpredictably. As components are added or changed, all the numbers need to be managed again — making it practically unmaintainable.

Focus trap required inside modals

When a modal opens, focus must be trapped inside. On close, return focus to the trigger element.

Glossary

Programmatic focus

Moving focus to a specific element by calling .focus() directly in JavaScript code, without user input. Used when opening or closing modals, and when navigating to an error field after form validation.

Accessibility Tree

A separate tree structure built by the browser from the DOM. Assistive technologies like screen readers read this tree, not the DOM directly. It includes role, aria-* attributes, and text content. Elements hidden with aria-hidden or display:none are excluded.

Focus Trap

A pattern that keeps Tab key navigation cycling within a specific container (e.g., a modal), preventing focus from reaching background content while the modal is open. Libraries like @radix-ui and react-focus-lock implement this.

Landmark

Semantic HTML elements or ARIA roles (header, nav, main, aside, footer) that divide the page structure. Screen reader users can jump between landmarks using keyboard shortcuts, allowing fast navigation to desired sections in long pages.

Virtualization

A technique that renders only the visible items in the DOM, removing the rest. Even with 1000 items, only the ~20 visible ones exist in the DOM. Reduces DOM node count and accessibility tree size, improving performance and assistive technology response time.