CtrlK
BlogDocsLog inGet started
Tessl Logo

accessibility-standards

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

Quality

100%

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Passed

No known issues

SKILL.md
Quality
Evals
Security

Accessibility Standards

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.

Cognitive

Plain language; consistent landmarks and nav order across pages; minimal distractions.

Keyboard

  • All interactive elements keyboard-navigable with visible focus in reading order.
  • No tabindex on static elements; tabindex="-1" only for elements receiving programmatic focus.
  • Hidden elements must not be focusable.

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.

Validation checkpoints (run-fix-repeat)

  • Run an automated audit: npx axe-core or integrate axe-core/axe-playwright in CI — fix high/critical findings.
  • Verify keyboard tab order manually: Tab through the page, ensure logical order and visible focus.
  • Confirm contrast ratios (spot-check key pages): use axe, pa11y, or contrast tools and ensure ≥4.5:1 for body text.
  • Fix, re-run audits, and repeat until no high/critical a11y issues remain.

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; }
KeyAction
TabNext interactive element
ArrowNavigate within composite component
EnterActivate focused control
EscapeClose dialogs/menus

Low Vision

RuleRequirement
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
ColorNever the sole conveyor of information

Screen Reader

  • Correct semantics (name, role, value, states). Prefer native HTML; ARIA only when necessary.
  • Landmarks: <header>, <nav>, <main>, <footer>.
  • One <h1> per page; <h1><h6> introduce sections; no skipping levels.

Voice Access

  • Interactive element accessible name must contain its visible label text.
  • aria-label must include the visible label.

Forms

  • Labels accurately describe control purpose.
  • Required fields: asterisk in label + aria-required="true".
  • Errors: aria-invalid="true" + aria-describedby pointing to error message.
  • Don't disable submit — show errors instead; focus first invalid field on submit.

Images

TypePattern
Informativealt="[meaning]" on <img>; role="img" + aria-label on <svg> / icon fonts
Decorativealt="" on <img>; aria-hidden="true" on role="img"

Input Labels

  • <label for="id"> for form inputs; all interactive elements need visible labels.
  • Disambiguate repeated labels (e.g., "Remove") with aria-label.
  • Help text via aria-describedby.

Navigation

<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>
  • Use <nav> + <ul>, NOT menu/menubar roles.
  • Toggle aria-expanded on expand/collapse; Escape closes menus.
  • Roving tabindex across main items; arrow down into sub-menus.

Page Title

  • <title> describes page purpose, unique per page.
  • Front-load unique info: "[Page] - [Section] - [Site]".

Tables & Grids

  • Column headers: <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).
Repository
monkilabs/opencastle
Last updated
Created

Is this your skill?

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.