WCAG 2.2 AA accessibility audit for a WordPress plugin's admin UI, block editor output, and frontend markup. Combines axe-core (automated 30% coverage) with code-review for the 70% axe can't catch — focus traps, keyboard nav, ARIA misuse, screen-reader announcements, colour contrast on dynamic content. Use when the user says "a11y", "accessibility", "WCAG", "axe-core", "screen reader", or after any UI change to the plugin's admin pages or block output.
Scanned 9/9/2026
Install to Claude Code
npx -y skills add adityaarsharma/orbit --skill orbit-accessibility --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Orbit Accessibility?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/adityaarsharma-orbit-accessibility)More formats (shields.io, HTML) on the badges page.
---
name: orbit-accessibility
description: WCAG 2.2 AA accessibility audit for a WordPress plugin's admin UI, block editor output, and frontend markup. Combines axe-core (automated 30% coverage) with code-review for the 70% axe can't catch — focus traps, keyboard nav, ARIA misuse, screen-reader announcements, colour contrast on dynamic content. Use when the user says "a11y", "accessibility", "WCAG", "axe-core", "screen reader", or after any UI change to the plugin's admin pages or block output.
---
# 🪐 orbit-accessibility — WCAG 2.2 AA audit
Two layers: **automated** (axe-core via Playwright) + **code review** (the 70% axe can't catch).
---
## Quick start
```bash
# Automated scan on every visual URL
WP_TEST_URL=http://localhost:8881 \
npx playwright test --project=a11y
# Plus code-review pass via Claude
claude "/orbit-accessibility Audit ~/plugins/my-plugin admin UI + frontend output for WCAG 2.2 AA. Output markdown."
```
Runs automatically as part of `/orbit-gauntlet --mode full` (Step 11 — accessibility-compliance audit).
---
## What axe-core catches (the 30%)
- Missing `alt` on `<img>`
- Form inputs without `<label>`
- Insufficient colour contrast (text vs background)
- Missing `lang` on `<html>`
- Empty buttons / links
- Duplicate IDs
- Heading order skipped (h1 → h3)
---
## What this skill catches (the 70%)
### Keyboard navigation
- ❌ Tab order doesn't follow visual order
- ❌ Focus disappears (`outline: none` without alternative)
- ❌ Modal opens but focus stays on the trigger button
- ❌ Modal closes but focus doesn't return to the trigger
- ❌ Custom dropdown not reachable by keyboard (uses `mousedown` only)
- ❌ Date picker / colour picker / range slider with no keyboard support
### Screen reader (ARIA)
- ❌ `<div role="button">` without `tabindex="0"` and key handlers
- ❌ Toast / notice appears but no `aria-live` region
- ❌ Form error appears but no `aria-describedby` link
- ❌ Loading spinner with no `aria-busy="true"`
- ❌ Toggle button switches state but no `aria-pressed`
- ❌ Tabs without `role="tablist"` / `role="tab"` / `aria-selected`
- ❌ Modal without `role="dialog"` + `aria-labelledby`
- ❌ Icon-only button without `aria-label`
- ❌ `aria-hidden="true"` on focusable element
### Dynamic content
- ❌ AJAX result inserted into DOM with no announcement
- ❌ Page change via `history.pushState` without focus management
- ❌ Auto-refresh of content without `aria-live="polite"`
- ❌ Form submission shows toast but doesn't move focus
### Colour & visual
- ❌ Information conveyed by colour alone (red = error, no icon)
- ❌ Hover-only affordance (no keyboard equivalent)
- ❌ Required field marked with `*` only (no text "Required")
- ❌ Touch target < 44×44px (WCAG 2.5.5)
### Forms (WCAG 3.3)
- ❌ Validation errors without `aria-invalid="true"`
- ❌ Error message only on submit (no inline validation hint)
- ❌ Generic error "Invalid input" instead of "Email must contain @"
- ❌ Labels disappearing on focus (placeholder-as-label anti-pattern)
### Block editor (Gutenberg)
- ❌ Custom block missing `supports.html` declaration
- ❌ InspectorControls without proper `__()` text
- ❌ Block toolbar buttons without `aria-label`
- ❌ Inline transforms with no preview / undo
---
## Report format
```markdown
# Accessibility Audit — [Plugin]
## Summary
- Pages scanned: 12
- WCAG 2.2 AA violations: 23
- Critical: 4 (block release)
- Serious: 8 (block release)
- Moderate: 7
- Minor: 4
## Critical findings
### 1. Modal focus trap missing
**File:** assets/js/admin/modal.js:42
**WCAG:** 2.4.3 Focus Order, 2.1.2 No Keyboard Trap
**Issue:** Modal opens via `dialog.show()` but focus stays on trigger button. Users on keyboard or screen reader can't navigate into the modal.
**Fix:**
```js
function openModal(modal) {
const focusable = modal.querySelectorAll('a, button, input, [tabindex]');
focusable[0]?.focus();
document.addEventListener('keydown', trapFocus);
}
```
### 2. Toast notice not announced
**File:** includes/admin/notice.php:18
**WCAG:** 4.1.3 Status Messages
**Issue:** `<div class="notice">` rendered but no `role="status"` or `aria-live`. Screen readers ignore the success/error message.
**Fix:**
```php
echo '<div class="notice notice-success" role="status" aria-live="polite">';
```
[Continue for all findings]
```
---
## Run on a URL list (CI-friendly)
```bash
A11Y_URLS=$(jq -r '.visualUrls | join(",")' qa.config.json) \
npx playwright test --project=a11y
```
Reads `visualUrls` from `qa.config.json`. Each URL gets its own axe-core scan.
---
## Pair with `/orbit-visual-regression`
Visual regression catches "did the UI change visually". This skill catches "is the UI usable for keyboard / screen reader / low-vision users". They overlap on **0%** — run both.
---
## Common false positives (don't fix these)
| Axe says | Why it's OK |
|---|---|
| `color-contrast` on disabled buttons | WCAG exempts disabled controls (1.4.3) |
| `region` rule on a single-purpose admin page | Admin pages are exempt — `<main>` is enough |
| `landmark-unique` in WP admin | WP core admin already has landmarks |
Document any "expected fail" in `tests/playwright/a11y-known-issues.md` so the next reviewer doesn't refile the same finding.
---
## Tools used
- `@axe-core/playwright` — automated WCAG scan
- `axe-core` 4.x rules → mapped to WCAG 2.2 AA
- Claude Code review for the 70% axe can't see
---
## Severity → release gate
| WCAG impact | Block release? |
|---|---|
| Critical (focus trap, keyboard not reachable) | ✅ Yes |
| Serious (no aria-label on icon button, no error association) | ✅ Yes |
| Moderate (colour alone, touch target < 44px) | ⚠ Document, fix in next release |
| Minor (lang attr, duplicate ID) | Log + defer |
---
## Standards reference
- [WCAG 2.2 AA Quick Reference](https://www.w3.org/WAI/WCAG22/quickref/)
- [WordPress Accessibility Coding Standards](https://make.wordpress.org/core/handbook/best-practices/coding-standards/accessibility-coding-standards/)
- [10up Accessibility Guide](https://10up.github.io/Engineering-Best-Practices/markup/#accessibility)
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!