agentleFS
andr-caandr-ca/agentharness/.claude/skills/accessibility/SKILL.md

accessibility

Skill1 starsChanged 2 months agoMITView on GitHub

Use when building or reviewing web UIs for accessibility — WCAG 2.2 Level AA compliance, semantic HTML over ARIA, keyboard navigation, color contrast, screen reader patterns, and testing approach.

We split this skill into the rules it gives an agent

4 rules. 0 are common, 1 is distinctive, and 3 are very specific to this project.

  • 0

    Common

    Most of the 97 edited versions we read keep these.

  • 1

    Distinctive

    This author's own choices. Worth a look.

  • 3

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Verify computed colors — don't eyeball.

    line 42
  2. Very specific:

    Keyboard: All interactive elements must be reachable by Tab, in logical order, with no keyboard trap.

    line 48
  3. Very specific:

    Visible focus: Never outline: none without a clearly visible replacement.

    line 51
  4. Very specific:

    Run axe-core in CI as a smoke test, not a complete audit.

    line 97

“Common” is measured: kept by at least 6 in 10 of the 97 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Accessibility

This skill is self-contained for day-to-day use. Deeper reference (needs the full harness checkout): patterns/accessibility/README.md (full examples including ARIA live regions and APG patterns). External canonical sources: WCAG 2.2 and the WAI-ARIA Authoring Practices.

Target: WCAG 2.2 Level AA.

The first rule: don't use ARIA if a native element exists

A native <button>, <a href>, <input>, <label>, <nav>, or <table> brings keyboard behavior, focus management, and the correct role/state for free. role="button" + tabindex + keyboard handler is a liability you now own forever.

<!-- Good: browser handles focus, Enter, Space, and role automatically -->
<button type="button" onclick="save()">Save</button>

<!-- Avoid: you must re-implement everything the native button provides -->
<div role="button" tabindex="0" onclick="save()" onkeydown="handleKey(event)">Save</div>

Perceivable

  • Text alternatives. Meaningful images: alt describing purpose. Decorative images: alt="". Icon-only controls: aria-label or visually-hidden text.
  • Contrast. Body text ≥ 4.5:1 against background. Large text (≥ 24px, or ≥ 18.66px bold) and UI components/graphics ≥ 3:1. Verify computed colors — don't eyeball.
  • Color alone is not enough. A red border and an error text/icon — not red alone.

Operable

  • Keyboard. All interactive elements must be reachable by Tab, in logical order, with no keyboard trap. tabindex="0" for natural order; tabindex="-1" for programmatic-only focus; never positive values.
  • Visible focus. Never outline: none without a clearly visible replacement. Keyboard users navigate by it.
  • Skip link. First focusable element on pages with repeated navigation: <a href="#main">Skip to main content</a>.
  • Target size. Interactive targets ≥ 24×24 px (WCAG 2.2 §2.5.8), with adequate spacing if smaller.

Understandable

  • Label every input. <label for> or aria-labelledby. Placeholder text is not a label — it disappears when the user starts typing.
  • Errors in text. On validation failure: describe what's wrong and how to fix it; associate via aria-describedby; set aria-invalid="true" on the field.
  • Consistent, predictable behavior. Focus doesn't jump unexpectedly; forms don't submit on focus change.

Robust

  • Name, Role, Value for every custom widget. Follow the matching ARIA APG pattern exactly — its roles, states, and keyboard interactions. A half-implemented ARIA widget is worse than a native element.
  • Announce dynamic changes. Content that updates without a page load (toasts, async results, validation) needs an aria-live region (polite for status updates, assertive only for urgent/time-sensitive changes) or role="alert".
<!-- Status message that updates asynchronously -->
<div aria-live="polite" aria-atomic="true" class="sr-only" id="status">
  <!-- Updated by JS: "3 items saved." -->
</div>

Testing: automated is not enough

Automated tools (axe-core, Lighthouse) catch ~30–50% of WCAG issues — contrast, missing labels/alt, invalid ARIA. The rest requires manual testing:

  1. Tab through every interactive element — confirm logical order, visible focus, no traps.
  2. Run a screen reader (NVDA + Firefox, VoiceOver + Safari) on each flow. Hear, don't just read, what's announced.
  3. Check at 200% browser zoom — layout must not break or lose content.
  4. Run axe-core in CI as a smoke test, not a complete audit.

Pitfalls to catch in review

// Missing alt — screen reader announces the file path
<img src="/hero.png" />  // WRONG
<img src="/hero.png" alt="Developer reviewing code" />  // RIGHT

// Form input with no label
<input type="email" placeholder="you@example.com" />  // WRONG
<label htmlFor="email">Email</label>
<input type="email" id="email" placeholder="you@example.com" />  // RIGHT

// Click handler on non-interactive element — keyboard users can't trigger
<div onClick={handleSave}>Save</div>  // WRONG
<button type="button" onClick={handleSave}>Save</button>  // RIGHT

// outline: none without a replacement focus style
button:focus { outline: none; }  // WRONG
button:focus-visible { outline: 2px solid #005fcc; outline-offset: 2px; }  // RIGHT

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

Reviews can't be read right now.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.