// 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.

native-html aria-required wcag-2.2 AA

// 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

    • native-html
    • beginner
  • 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

    • aria-required
    • intermediate
  • Breadcrumb

    Location indicator using native <nav> with <ol> and aria-current="page". CSS-only separators, zero JavaScript.

    WCAG 2.4.8 Location, 1.3.1 Info and Relationships

    • native-html
    • beginner
  • 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

    • aria-required
    • intermediate
  • 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

    • native-html
    • intermediate
  • Mega Menu

    Multi-column dropdown navigation with grouped links, aria-expanded triggers, keyboard navigation, and focus management.

    WCAG 1.3.1 Info and Relationships, 2.1.1 Keyboard

    • aria-required
    • intermediate
  • Pagination

    Page navigation with a <nav> landmark, real links, and aria-current="page". Works without JavaScript and survives refresh.

    WCAG 2.4.8 Location, 2.4.4 Link Purpose

    • native-html
    • beginner
// interactive

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

    • native-html
    • beginner
  • 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

    • native-html
    • intermediate
  • Data Table

    Sortable data table with native <table>, <caption>, <th scope>, and aria-sort for sort state.

    WCAG 1.3.1 Info and Relationships, 4.1.2 Name, Role, Value

    • native-html
    • intermediate
  • Switch / Toggle

    Toggle switch using <button> with role="switch" and aria-checked. CSS-animated knob with reduced motion support.

    WCAG 4.1.2 Name, Role, Value, 2.1.1 Keyboard

    • aria-required
    • intermediate
  • Toast / Notification

    Live region notifications with role="status" and role="alert". Auto-dismiss pauses on hover/focus.

    WCAG 4.1.3 Status Messages, 2.2.1 Timing Adjustable

    • aria-required
    • intermediate
  • Tooltip

    Tooltip with role="tooltip" and aria-describedby. Shows on hover and focus, dismisses with Escape. Includes toggletip variant.

    WCAG 1.4.13 Content on Hover or Focus

    • aria-required
    • intermediate
  • Carousel / Slider

    Auto-rotating content carousel with pause control, dot indicators, aria-roledescription, keyboard navigation, and aria-live announcements.

    WCAG 2.2.2 Pause, Stop, Hide, 4.1.2 Name, Role, Value

    • aria-required
    • intermediate
  • 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

    • aria-required
    • advanced
  • 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

    • aria-required
    • advanced
  • Alert / Banner

    Persistent inline messages with the right ARIA live region role. Distinguishes role="alert" (urgent) from role="status" (polite).

    WCAG 4.1.3 Status Messages, 1.4.1 Use of Color

    • aria-required
    • intermediate
  • 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

    • native-html
    • beginner
  • Button

    Native <button> with proper type. Covers icon-only buttons, toggle buttons with aria-pressed, loading states, and disabled vs aria-disabled.

    WCAG 2.1.1 Keyboard, 4.1.2 Name, Role, Value

    • native-html
    • beginner
  • Card

    Clickable card with a single anchor and ::after expansion. 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

    • native-html
    • intermediate
// forms

Forms

3 patterns
  • Accessible Forms

    Proper <label> association, <fieldset>/<legend> grouping, inline validation with aria-invalid, and accessible error messages.

    WCAG 1.3.1 Info and Relationships, 3.3.1 Error Identification

    • native-html
    • intermediate
  • Combobox / Autocomplete

    Filterable input with role="combobox", aria-activedescendant for virtual focus, and live region result count announcements.

    WCAG 4.1.2 Name, Role, Value, 2.1.1 Keyboard

    • aria-required
    • advanced
  • 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

    • native-html
    • beginner

// 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.