// 23 patterns · native html first · aria only when needed
Accessible Component Patterns
23 production-ready accessible component patterns, each built native-HTML-first with ARIA added only where the platform leaves a gap. Every pattern includes a live demo, complete source code, a keyboard interaction guide, screen reader behavior notes, common mistakes to avoid, and a full WCAG 2.2 success-criteria mapping. Browse by category below, or read on for how to choose.
// what is this
What is an accessible component pattern?
An accessible component pattern is a reusable, tested implementation of a common UI component — a modal, a tab set, a combobox — built so it works for everyone: keyboard-only users, screen reader users, people using voice control or switch devices, and everyone else. A complete pattern specifies the exact roles, states, keyboard interactions, and focus behavior the component needs, and backs them with working code you can copy into your project.
These patterns follow the guidance in the W3C's ARIA Authoring Practices Guide, but go further than the spec: each one shows the native HTML baseline first, explains exactly where ARIA is genuinely required, documents how real screen readers (NVDA, JAWS, VoiceOver) announce the component, and lists the common mistakes that quietly break it. The goal is that you can ship the component without second-guessing.
// the rule
Native HTML first, ARIA only when needed
The single most important principle in accessible component development: don't reach for ARIA when a native HTML element already does the job. A native <button>, <a>, <details>, <dialog>, or <input> ships with built-in roles, states, focus behavior, and keyboard handling that you would otherwise have to rebuild — correctly — with ARIA and JavaScript. The native version is shorter, more robust, and far harder to get wrong.
ARIA earns its place when HTML has no native equivalent — tabs, comboboxes, tree views, and similar rich widgets. For those, the ARIA guide explains how to apply roles and states correctly. Every pattern below is tagged so you can see the tradeoff at a glance:
- native-html works with little or no ARIA; the native element carries the semantics.
- aria-required no native equivalent exists, so ARIA is necessary.
- beginner intermediate advanced how much complexity the pattern involves, so you know where to start.
// choosing a pattern
Which pattern do I need?
All 23 patterns are grouped into three categories below. If you're starting from a task, this map points you to the right one:
Overlays and dialogs
Content that appears on top of the page. Use the modal dialog when the user must respond before continuing, the alert / alertdialog for urgent interruptions, the toast for transient notifications, and the tooltip for supplementary hints on focus or hover.
Expanding and collapsing content
The accordion and disclosure patterns show and hide content with native <details> where possible. For tabbed views, the tabs pattern manages roving focus and panel association.
Navigation
Start every page with skip links. Use the breadcrumb for hierarchy, pagination for paged lists, the responsive nav and mega menu for site headers, and the dropdown menu for action menus.
Forms and inputs
The accessible forms pattern covers labels, grouping, validation, and errors. For specialized inputs, see the combobox, date picker, search field, and switch.
Once you've built a component, verify it against the Developer Accessibility Checklist and test it with the Accessibility Testing Checklist.
// browse by category
Browse by category
All 23 patterns, grouped by category. Each card's code-strip shows the element it's built on; the mono line is its primary WCAG criterion.
Navigation
7 patterns-
Skip Links
Visually hidden bypass links that appear on focus, letting keyboard users skip past navigation to the main content.
WCAG 2.4.1 Bypass Blocks
-
Tabs
Tabbed interface with ARIA roles, arrow key navigation, roving tabindex, and automatic panel association. No native HTML equivalent.
WCAG 4.1.2 Name, Role, Value
-
Breadcrumb
Location indicator using native
<nav>with<ol>andaria-current="page". CSS-only separators, zero JavaScript.WCAG 2.4.8 Location, 1.3.1 Info and Relationships
-
Dropdown Menu
Button-triggered menu with
role="menu", arrow key navigation, Escape to close, and focus management on open/close.WCAG 2.1.1 Keyboard, 4.1.2 Name, Role, Value
-
Responsive Navigation
Desktop-to-mobile nav with hamburger button,
aria-expanded, focus management, and Escape to close.WCAG 2.4.1 Bypass Blocks, 2.1.1 Keyboard
-
Mega Menu
Multi-column dropdown navigation with grouped links,
aria-expandedtriggers, keyboard navigation, and focus management.WCAG 1.3.1 Info and Relationships, 2.1.1 Keyboard
-
Pagination
Page navigation with a
<nav>landmark, real links, andaria-current="page". Works without JavaScript and survives refresh.WCAG 2.4.8 Location, 2.4.4 Link Purpose
Interactive Components
13 patterns-
Accordion
Expandable content sections using native
<details>and<summary>. Keyboard accessible with zero JavaScript.WCAG 4.1.2 Name, Role, Value, 2.1.1 Keyboard
-
Modal Dialog
Accessible modal built on the native
<dialog>element. Focus trapping, Escape to close, return focus, and backdrop dismissal.WCAG 2.4.3 Focus Order, 2.1.2 No Keyboard Trap
-
Data Table
Sortable data table with native
<table>,<caption>,<th scope>, andaria-sortfor sort state.WCAG 1.3.1 Info and Relationships, 4.1.2 Name, Role, Value
-
Switch / Toggle
Toggle switch using
<button>withrole="switch"andaria-checked. CSS-animated knob with reduced motion support.WCAG 4.1.2 Name, Role, Value, 2.1.1 Keyboard
-
Toast / Notification
Live region notifications with
role="status"androle="alert". Auto-dismiss pauses on hover/focus.WCAG 4.1.3 Status Messages, 2.2.1 Timing Adjustable
-
Tooltip
Tooltip with
role="tooltip"andaria-describedby. Shows on hover and focus, dismisses with Escape. Includes toggletip variant.WCAG 1.4.13 Content on Hover or Focus
-
Carousel / Slider
Auto-rotating content carousel with pause control, dot indicators,
aria-roledescription, keyboard navigation, andaria-liveannouncements.WCAG 2.2.2 Pause, Stop, Hide, 4.1.2 Name, Role, Value
-
Date Picker
Calendar date picker with
role="grid", keyboard grid navigation, text input fallback, and screen reader announcements.WCAG 2.1.1 Keyboard, 4.1.2 Name, Role, Value
-
Tree View
Hierarchical tree with
role="tree", expandable/collapsible nodes, roving tabindex, and arrow key navigation.WCAG 1.3.1 Info and Relationships, 4.1.2 Name, Role, Value
-
Alert / Banner
Persistent inline messages with the right ARIA live region role. Distinguishes
role="alert"(urgent) fromrole="status"(polite).WCAG 4.1.3 Status Messages, 1.4.1 Use of Color
-
Disclosure
Single show/hide widget using native
<details>/<summary>. The flagship native-first pattern — zero JavaScript, zero ARIA.WCAG 4.1.2 Name, Role, Value, 2.4.4 Link Purpose
-
Button
Native
<button>with propertype. Covers icon-only buttons, toggle buttons witharia-pressed, loading states, and disabled vsaria-disabled.WCAG 2.1.1 Keyboard, 4.1.2 Name, Role, Value
-
Card
Clickable card with a single anchor and
::afterexpansion. Avoids nested-link traps and<div onclick>anti-patterns. Multi-action card variant included.WCAG 2.4.4 Link Purpose, 2.5.5 Target Size
Forms
3 patterns-
Accessible Forms
Proper
<label>association,<fieldset>/<legend>grouping, inline validation witharia-invalid, and accessible error messages.WCAG 1.3.1 Info and Relationships, 3.3.1 Error Identification
-
Combobox / Autocomplete
Filterable input with
role="combobox",aria-activedescendantfor virtual focus, and live region result count announcements.WCAG 4.1.2 Name, Role, Value, 2.1.1 Keyboard
-
Search Field
Search form with
role="search"landmark, accessible label, clear button, results count live region, and recent searches list.WCAG 1.3.1 Info and Relationships, 4.1.3 Status Messages
// frequently asked
Frequently asked questions
What is an accessible component pattern?
An accessible component pattern is a reusable, tested implementation of a common UI component — a modal, a tab set, a combobox — built so it works for everyone: keyboard-only users, screen reader users, people using voice control or switch devices, and everyone else. A complete pattern specifies the required roles, states, keyboard interactions, and focus behavior, and backs them with working code.
Do I need ARIA to build accessible components?
Often, no. The first rule of ARIA is: don't use ARIA if a native HTML element provides the semantics you need. A native <button>, <a>, <details>, <dialog>, or <input> comes with built-in roles, states, and keyboard behavior you'd otherwise have to recreate with ARIA and JavaScript — and get exactly right. ARIA is essential for components HTML doesn't provide natively (tabs, comboboxes, tree views), but for many patterns the most accessible solution uses little or no ARIA. See the ARIA guide for the full decision tree.
Are these patterns production-ready?
Yes. Each pattern is a complete, copy-paste implementation with HTML, CSS, and JavaScript, tested against the keyboard and screen reader behaviors documented on its page. They're built to WCAG 2.2 Level AA as a baseline (AAA where reasonable) and avoid the common shortcuts — clickable <div>s, removed focus outlines, missing labels — that break real-world components.
What's the difference between a pattern and a guide?
A pattern is component-specific: it shows you how to build one thing (a modal, a set of tabs) correctly, with working code. A guide is conceptual: it explains a cross-cutting topic (focus management, ARIA, color contrast) that applies across many components. Use a pattern when you're building a specific component; read a guide when you want to understand the underlying principle. The two cross-link heavily.
Do these patterns work with React, Vue, and other frameworks?
Yes. The patterns are written in vanilla HTML, CSS, and JavaScript so they're framework-agnostic — the accessibility requirements (roles, states, keyboard handling, focus management) are identical regardless of how you render the markup. Porting to React or Vue is mechanical: the semantics and interactions stay the same. For framework-specific gotchas, see the React and SPA accessibility checklists.
How do I choose the right pattern?
Start from the task. If you need an overlay that demands a response, that's the modal pattern. Expanding content is the accordion or disclosure pattern. Navigation is skip links, breadcrumb, tabs, or menus depending on the structure. The "Which pattern do I need?" section above groups all 23 patterns by task and by category, and each pattern's difficulty tag tells you how much complexity to expect.