Skip to content
cccskills
FreePublished on GitHub

wcag-keyboard-navigation

Reference catalog for WCAG 2.2 keyboard-navigation conformance - covers SC 2.1.1 (Keyboard), 2.1.2 (No Keyboard Trap), 2.1.4 (Character Key Shortcuts), 2.4.3 (Focus Order), 2.4.7 (Focus Visible), 2.4.11/2.4.12 (Focus Not Obscured) - with conformance levels (A/AA), test scripts, and per-criterion failure patterns, plus the modal focus-trap / focus-management pattern (focus-on-open, Tab-cycle, inert, Escape-closes, restore-to-trigger, native `<dialog>`) in references/. Use when authoring or reviewing keyboard-only interaction support, or a modal / drawer / popover's focus management.

The English summary is being prepared. Showing the original description.

testland/qa13 stars(GitHub 13 + cccskills 0)

Run score Not tested

See how to install

Files included (13)

  • SKILL.md10.6 KB
  • .tessl-plugin/plugin.json728 B
  • evals/aa-signoff-on-a-checkout-with-two-sticky-bars/criteria.json5.6 KB
  • evals/aa-signoff-on-a-checkout-with-two-sticky-bars/task.md8.8 KB
  • evals/kanban-cards-that-only-move-by-mouse/criteria.json5.0 KB
  • evals/kanban-cards-that-only-move-by-mouse/task.md8.7 KB
  • evals/power-user-shortcuts-archiving-mail-nobody-touched/criteria.json5.3 KB
  • evals/power-user-shortcuts-archiving-mail-nobody-touched/task.md7.2 KB
  • evals/procurement-audit-finding-on-our-hand-rolled-dialog/criteria.json5.8 KB
  • evals/procurement-audit-finding-on-our-hand-rolled-dialog/task.md8.7 KB
  • evals/tab-strip-where-arrows-move-the-panel-but-not-the-reader/criteria.json5.0 KB
  • evals/tab-strip-where-arrows-move-the-panel-but-not-the-reader/task.md8.0 KB
  • references/focus-trap.md9.8 KB

SKILL.md (original)

Review the instructions the agent will receive before you install.

wcag-keyboard-navigation

Reference catalog for how to verify keyboard-navigation conformance. Pairs with the scanner umbrella axe-a11y (axe-core, pa11y, Lighthouse a11y).

Overview

WCAG 2.2 organizes accessibility into four principles - Perceivable / Operable / Understandable / Robust - at three conformance levels - A / AA / AAA (wcag22).

Keyboard navigation lives under Operable (Principle 2) and spans six key Success Criteria covering keyboard operability, focus management, and focus visibility.

When to use

  • Reviewing a component's keyboard interaction surface during PR review.
  • Authoring a keyboard-navigation test plan for a new component.
  • Triaging an accessibility audit finding tagged with one of the SCs below.
  • Configuring per-rule severities for axe-a11y.

Success Criteria

SC 2.1.1 - Keyboard (Level A)

Per wcag22: "All functionality of the content is operable through a keyboard interface" without requiring specific timings. Path-dependent input (handwriting) is exempt.

PatternWhat to test
<button>, <a href>, <input>Native - already keyboard-accessible.
<div onclick="...">Anti-pattern. Non-focusable; not keyboard-operable. Convert to <button>.
Custom widget (role="button", tabindex="0")Verify Enter / Space activates the same handler.
Drag-and-dropProvide a keyboard alternative (arrow keys + Enter, or button-based reorder).

Test script (Playwright):

test('SC 2.1.1 - interactive elements are keyboard-operable', async ({ page }) => {
  // Tab to the button, activate with Enter
  await page.keyboard.press('Tab');
  await page.keyboard.press('Enter');
  await expect(page.locator('[data-testid="action-result"]')).toBeVisible();

  // Repeat with Space for elements that should accept Space
  await page.keyboard.press('Tab');
  await page.keyboard.press('Space');
  await expect(...).toBeVisible();
});

SC 2.1.2 - No Keyboard Trap (Level A)

Per wcag22: "Focus must be movable away using standard methods; users should be informed of exit procedures if non- standard keys are required."

Common failureFix
Modal traps Tab without an explicit Escape handlerAdd Escape handler that closes the modal and restores focus.
Embedded <iframe> (e.g. third-party widget) traps TabSet tabindex="-1" on the iframe OR document the exit (Esc + Tab) in surrounding label.
Custom date picker locks focus inside on first focusProvide Tab to exit the calendar and continue to the next field.

See references/focus-trap.md for the intentional-trap convention (modal focus management) which is distinct from a violation.

SC 2.1.4 - Character Key Shortcuts (Level A, added in 2.1)

Single-character shortcuts (/ to focus search, j/k to navigate items) must offer at least one of:

  • Off mechanism - user can disable the shortcut globally.
  • Remap mechanism - user can rebind to non-character or modifier-prefixed combinations.
  • Active only on focus - shortcut active only when the associated component has focus.

This SC exists because users with speech-input software produce spurious key presses; unguarded single-character shortcuts trigger unintended actions.

SC 2.4.3 - Focus Order (Level A)

Per wcag22: components must "receive focus in an order that preserves meaning and operability."

PatternWhat to test
Reading-order vs DOM-order vs visual-orderAll three should agree. CSS order / flex-direction: row-reverse can desync visual from DOM.
tabindex="3" (positive)Anti-pattern. Positive tabindex creates explicit focus order separate from DOM; rarely intended. Use 0 or -1.
Modal that doesn't trap focusTab moves focus to the page behind; user loses context.
Skip linksAlways at the start of the document; tabindex="0" not needed (anchor links are focusable).

SC 2.4.7 - Focus Visible (Level AA)

Per wcag22: "Any keyboard operable user interface has a mode of operation where the keyboard focus indicator is visible."

FailureFix
*:focus { outline: none; } without alternativeReplace with :focus-visible style: :focus-visible { outline: 2px solid var(--focus-ring); }.
Subtle 1px gray ring on a gray background3:1 contrast ratio against background per WCAG SC 1.4.11; high-contrast theme should bump to 4.5:1.
Disabled focus indicator on hoverHover and focus styles are independent; never tie them.

SC 2.4.11 / 2.4.12 - Focus Not Obscured (Level AA / AAA, NEW in 2.2)

Per wcag22: components receiving focus cannot be "entirely hidden due to author-created content."

Failure patternFix
Sticky header covers the focused input on long-form pagesAdjust scroll-margin-top so focused element scrolls into view below the sticky header.
Persistent cookie banner covers focused elementModal / overlay should NOT obscure focused content; use compact banner or temporarily hide.
Auto-popup chat widget overlays focused fieldsRender below other content OR move to a corner that doesn't intersect with form fields.

2.4.11 (Minimum, Level AA): focus must NOT be entirely obscured.

2.4.12 (Enhanced, Level AAA): focus must NOT be partially obscured. Stricter; relevant for high-stakes forms.

Per-component test patterns

Form

  1. Tab through every field; verify focus order matches reading order.
  2. Verify each interactive element has a visible focus ring.
  3. Verify label-input association via <label for="..."> or aria-labelledby.
  4. Activate submit via Enter from any field.
  5. After submit error: verify focus moves to the first invalid field (per SC 3.3.1 - Error Identification).

Modal / dialog

  1. On open: focus moves to the first interactive element (or to the dialog's close button if no other focusable element).
  2. Tab cycles through dialog content only - does NOT escape to page behind.
  3. Shift+Tab from first → last interactive element (cycle).
  4. Escape closes the dialog and returns focus to the trigger.

(See references/focus-trap.md for the full modal pattern.)

Menu / dropdown

  1. Tab focuses the trigger.
  2. Enter / Space / Down-arrow opens the menu; first item focused.
  3. Down/Up arrows navigate items; Home/End jump to first/last.
  4. Enter / Space activates the focused item.
  5. Escape closes the menu and returns focus to the trigger.

This matches the ARIA Menu pattern (referenced from aria-authoring-patterns).

Tabs

  1. Tab focuses the active tab (one tabstop per tab group).
  2. Left/Right arrows navigate between tabs (no Tab key).
  3. Activation: automatic on focus OR explicit on Enter/Space (manual activation; ARIA Authoring Practices defaults).
  4. After tab change: Tab moves to the panel content.

CI integration

The patterns above translate to per-test assertions in axe-a11y configurations. The a11y-violation-gate skill gates the build on new violations of these SCs.

Anti-patterns

Anti-patternWhy it failsFix
<div onclick> for buttonsNot focusable, not Enter-activatable.Always <button type="button">.
outline: none for clean designRemoves focus indicator entirely (SC 2.4.7).:focus-visible { outline: 2px solid <color>; }.
tabindex="3" to control focus orderCreates a non-DOM order; breaks on dynamic content.DOM-order tabbing; tabindex="0" for custom focusables, -1 to skip.
Single-character shortcuts always-activeTriggered by speech-input users (SC 2.1.4).Off / remap / focus-only.
Sticky header obscures focused inputViolates SC 2.4.11.scroll-margin-top per element.

References

  • wcag22 - WCAG 2.2 specification.
  • references/focus-trap.md - focus management for modals (the intentional-trap pattern, 6 steps, native <dialog>, test scripts).
  • wcag-color-contrast - for SC 1.4.11 focus-indicator contrast.
  • aria-authoring-patterns - for canonical interactive-widget patterns.
  • axe-a11y - scanners that detect SC violations programmatically.

Reviews

No reviews yet. Tell others what you thought.

Comments

No login needed. Share how it worked for you, ask a question, or note where it did not run.

No comments yet. Be the first to write one.

Comments are published right away. Do not include personal information such as email addresses or phone numbers. Up to 2 URLs.

0 / 1,000 characters

This form is protected by reCAPTCHA, and the Google Privacy Policy and Terms of Service apply.

More skills from this repository

Builds a CI gate that fails the build on **new** WCAG / a11y violations introduced by a PR while grandfathering pre-existing violations on a per-rule / per-page baseline. Aggregates verdicts from axe-core / pa11y / Lighthouse a11y / WAVE / IBM Equal Access scans. Use when a project has accumulated a11y debt and a strict "zero violations" gate would block every PR - the ratchet pattern lets the team ship while preventing regressions.

The English summary is being prepared. Showing the original description.

testland/qa13Updated Oct 20, 2026

Workflow skill that builds an A/B-test validity checklist from an experiment proposal, walking the canonical design-correctness gates - pre-registered OEC/power/guardrails, randomization unit + SRM check, assignment integrity, telemetry, peeking discipline, novelty/primacy, post-experiment SRM re-check - into a per-experiment checklist + sign-off form. Use when launching, auditing, or governing an experiment. For pitfall mechanics (guardrails, peeking) see experiment-results-interpreter's references; to read an already-valid result use experiment-results-interpreter; for per-SDK harness tests use experiment-sdk-testing - this gates DESIGN, not SDK code.

The English summary is being prepared. Showing the original description.

testland/qa13Updated Oct 20, 2026

The single install-flow skill: the reference contract for the PWA install flow (installability gate fields, `beforeinstallprompt` handshake, per-platform paths - Android WebAPK / iOS Share menu / Firefox no-op - and the `display-mode` post-install signal, in references/install-flow-reference.md) plus the build-an-X workflow that emits the Add-to-Home-Screen suite. Walks the four-stage timeline, emitting one test per gate cell per [web.dev/articles/install-criteria][install-criteria], the deferred-prompt → `prompt()` → `userChoice` chain per [web.dev/articles/customize-install][customize-install], the iOS Safari manual-metadata branch (`apple-touch-icon`) per [web.dev/learn/pwa/installation][learn-pwa], and the post-install `(display-mode: standalone)` MQ assertion. Output: a Playwright spec with per-stage cells plus a coverage matrix. Use when a PWA's manifest, icons, or install handler change, when install conversion drops at an unknown stage, or when triaging a flaky install assertion.

The English summary is being prepared. Showing the original description.

testland/qa13Updated Oct 20, 2026

Build-an-X workflow that uses an LLM to map existing tests to spec sections - given a spec doc + the test suite, the LLM identifies which tests cover which sections, surfaces uncovered sections (gap), and recommends specific tests to add. Output is a coverage matrix per spec ID. Scope is mapping tests that already exist and naming the gaps, not authoring tests for new acceptance criteria. Use when a spec doc and a test suite both exist but nobody can say which requirements are actually covered - before a release sign-off, an audit, or a decision about where to spend the next round of test effort.

The English summary is being prepared. Showing the original description.

testland/qa13Updated Oct 20, 2026

Generates tests from natural-language specs (acceptance criteria, user stories, requirements) using an LLM, with confidence scoring per test case (LLM self-assessment plus heuristics: assertion quality, naming, completeness), batching uncertain cases for human review, and integration with the team's existing test framework. Use when the user asks to generate unit tests from acceptance criteria, convert user stories to test cases, automate test creation from requirements, or augment a spec-driven test suite with AI-generated stubs that are then curated before merge.

The English summary is being prepared. Showing the original description.

testland/qa13Updated Oct 20, 2026

Configures Allure Report (test-runner adapter install, `allure-results` directory wiring, `categories.json` for failure classification, `history-trend.json` retention via the copy-history-between-runs pattern), runs the Allure CLI to convert `allure-results` to a static HTML site, and uploads the report as a CI artifact. Use when the team needs richer test reporting than JUnit XML - step-level attachments, per-test history, retry tracking, and severity / epic / feature labeling across framework-agnostic adapters (pytest, Jest, JUnit, TestNG, NUnit, Mocha). As a rich static HTML report generator, it is the open-source alternative to the sunset ExtentReports (JVM/.NET per-test HTML narrative); for hosted cross-run flakiness analytics rather than a static per-run report use currents-integration.

The English summary is being prepared. Showing the original description.

testland/qa13Updated Oct 20, 2026

See all skills by testland

Report a problem with this skill