WCAG 2.2 Level AA accessibility patterns for React/HTML/CSS. Use when creating or modifying UI components, forms, navigation, tables, images, or any user-facing elements. Covers keyboard navigation, screen reader semantics, low vision contrast, voice access, and inclusive language.
100
100%
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Passed
No known issues
Code must conform to WCAG 2.2 Level AA.
Workflow: Plan accessible implementation → generate → review against WCAG 2.2 → iterate. Suggest Accessibility Insights for testing.
Language: People-first ("person using a screen reader," not "blind user"). No ability stereotypes. Flag uncertain implementations with reasoning.
Plain language; consistent landmarks and nav order across pages; minimal distractions.
tabindex on static elements; tabindex="-1" only for elements receiving programmatic focus.Composite components and detailed complex patterns have been moved to REFERENCE.md to keep this skill focused. See REFERENCE.md for roving tabindex, aria-activedescendant, and composite widget examples.
npx axe-core or integrate axe-core/axe-playwright in CI — fix high/critical findings.Tab through the page, ensure logical order and visible focus.axe, pa11y, or contrast tools and ensure ≥4.5:1 for body text.Skip link (first focusable element):
<a href="#maincontent" class="sr-only">Skip to main</a>
<main id="maincontent"></main>.sr-only:not(:focus):not(:active) { clip: rect(0 0 0 0); clip-path: inset(50%); height: 1px; overflow: hidden; position: absolute; white-space: nowrap; width: 1px; }| Key | Action |
|---|---|
Tab | Next interactive element |
Arrow | Navigate within composite component |
Enter | Activate focused control |
Escape | Close dialogs/menus |
| Rule | Requirement |
|---|---|
| Text contrast | ≥4.5:1 (≥3:1 for large text: 18.5px bold / 24px) |
| Graphics/controls | ≥3:1 with adjacent colors |
| State indicators (pressed, focus, checked) | ≥3:1 |
| Color | Never the sole conveyor of information |
<header>, <nav>, <main>, <footer>.<h1> per page; <h1>–<h6> introduce sections; no skipping levels.aria-label must include the visible label.aria-required="true".aria-invalid="true" + aria-describedby pointing to error message.| Type | Pattern |
|---|---|
| Informative | alt="[meaning]" on <img>; role="img" + aria-label on <svg> / icon fonts |
| Decorative | alt="" on <img>; aria-hidden="true" on role="img" |
<label for="id"> for form inputs; all interactive elements need visible labels.aria-label.aria-describedby.<nav><ul>
<li><button aria-expanded="false" tabindex="0">Section 1</button>
<ul hidden><li><a href="..." tabindex="-1">Link 1</a></li></ul>
</li>
</ul></nav><nav> + <ul>, NOT menu/menubar roles.aria-expanded on expand/collapse; Escape closes menus.<title> describes page purpose, unique per page."[Page] - [Section] - [Site]".<th> in first <tr>; row headers: <th> in each row.role="gridcell" nested within role="row".<table> for static data; role="grid" for interactive (date pickers, calendars).f5c8508
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.