connorads/dotfiles

accessibility

Audit, implement, and fix web accessibility with a screen-reader-first lens. Use when building or reviewing UI components, forms, dialogs, navigation, dynamic content, or any interactive element. Covers WCAG 2.2 AA compliance, ARIA patterns, keyboard navigation, focus management, and assistive technology compatibility (NVDA, JAWS, VoiceOver). Trigger on: "accessible", "a11y", "screen reader", "WCAG", "ARIA", or when adding any interactive UI.

First seen Feb 27, 2026

Installation

$ npx skills add connorads/dotfiles --skill accessibility

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from connorads/dotfiles · top by installs.

npx skills add connorads/dotfiles

Browse all from connorads/dotfiles

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Repository health

Stars 16
Default branch master
Open issues 6
Status Active

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 10,891 B
  • docs SUMMARY.md 467 B

History

  1. First seen on skills.sh
  2. First recorded snapshot · 52 installs

SKILL.md

Accessibility

Web accessibility done right means your UI is navigable, understandable, and operable by people with disabilities - screen reader users, keyboard-only users, and people with low vision, motor, or cognitive impairments. This skill takes a screen-reader-first lens because it surfaces structural failures fastest, but low-vision users (contrast, zoom, reflow) and cognitive users matter just as much - in fact low-contrast text is the single most common barrier on the web, affecting ~84% of home pages. The WebAIM Million consistently finds ~96% of home pages carry detectable WCAG failures, and just six issue types - low-contrast text, missing alt text, missing form labels, empty links, empty buttons, and missing document language - account for ~96% of all detected failures and have topped the WebAIM Million findings every year they have been published (see link). Most are preventable with the right mental model.

The Core Mental Model

Screen readers linearise a 2D page into a 1D audio stream. A blind user never sees the whole page at once - they navigate sequentially by headings, landmarks, form fields, links, and interactive controls using keyboard shortcuts. Every decision you make should answer: "What will a screen reader announce, and does it make sense in isolation?"

The three rules that flow from this:

  1. Semantics over style - use native HTML elements (<button>, <nav>, <h2>) before reaching for ARIA. Native elements come with free keyboard support, accessible names, and correct roles.
  2. Context must travel with the element - a screen reader user navigating by tab or by links list sees elements stripped of their visual neighbours. Labels, descriptions, and states must be programmatically attached, not implied by proximity.
  3. Dynamic changes must be announced - screen readers only notice changes if focus moves to new content or a live region announces it. Silent DOM mutations are invisible to AT.

When Auditing Existing UI

Review in this priority order - fix critical issues before polishing low-impact ones:

Priority Category WCAG Level See
1 Accessible names (buttons, inputs, links) A references/aria-patterns.md
2 Keyboard operability (all interactive elements) A references/focus-management.md
3 Focus management (dialogs, SPAs, live regions) A/AA references/focus-management.md
4 Semantic structure (headings, landmarks, lists) A references/wcag-checklist.md
5 Form errors and validation A/AA references/common-fixes.md
6 Colour contrast and visual states AA references/wcag-checklist.md
7 Dynamic content announcements AA references/aria-patterns.md
8 Images and media A references/wcag-checklist.md
9 Motion, flashing, and timing (reduced-motion, seizure safety, auto-updating content) A/AA references/wcag-checklist.md

Quote the exact failing snippet, name the WCAG criterion, and propose the smallest viable fix. Do not refactor unrelated code.


When Building New UI

The quick decision tree

Need an interactive control?
  ↓
Does a native HTML element do this?  → YES → Use it. Done.
  ↓ NO
Use the correct ARIA role + required attributes + keyboard handler.

Adding dynamic content?
  ↓
Does focus move to the new content? → YES → No live region needed.
  ↓ NO
Is it a transient status (toast, cart count, form error)?
  → Use aria-live="polite" (or role="alert" for errors)

Opening a dialog/modal?
  → Trap focus inside. Restore focus to trigger on close.
  → See references/focus-management.md

Mandatory checks before shipping any interactive component

  • Every input, select, textarea has an associated <label> (not just placeholder)
  • Every button has an accessible name (text content, aria-label, or aria-labelledby)
  • Every icon-only control has aria-label; the icon has aria-hidden="true"
  • Focus is visible on all interactive elements (never outline: none without a replacement)
  • Tab order is logical and matches visual order
  • All pointer interactions have a keyboard equivalent
  • No tabindex greater than 0
  • Interactive targets are at least 24×24 CSS px, or spaced apart (WCAG 2.5.8)
  • Non-essential motion respects prefers-reduced-motion; nothing flashes more than three times per second (WCAG 2.3.1)

Five High-Impact Screen-Reader Failures (and their fixes)

These are the failures you will hit most through this skill's screen-reader lens. (The highest-volume failures site-wide - low-contrast text, missing alt - are covered under Colour and Contrast and Images below.)

  1. Icon-only button with no accessible name - announces bare "button"; needs aria-label on the button, aria-hidden="true" on the icon.
  2. Input with no label - placeholder is not a label; needs an associated <label for>.
  3. div or span used as a button - no keyboard support, no role; use <button>.
  4. Error not linked to its field - visually adjacent text is silent; link with aria-describedby + aria-invalid.
  5. Dynamic content updated silently - DOM mutations are invisible to AT without a live region.

Before/after fixes for all five: references/common-fixes.md (fixes 1, 2, 5, 3, and 23 respectively).


Screen Reader Testing

Automated tools catch ~30-40% of accessibility issues. The rest require AT testing.

Minimum viable test matrix:

  • NVDA + Firefox or Chrome (Windows) - free, strict, and one of the two most-used desktop readers
  • VoiceOver + Safari (macOS/iOS) - the dominant reader across Apple platforms
  • JAWS + Chrome for enterprise contexts - the other leading desktop reader

Core navigation patterns to test manually:

  1. Tab through all interactive elements - are names and roles announced correctly?
  2. Press H to navigate by headings - is the page structure logical?
  3. Press D to navigate by landmarks - are regions clearly labelled?
  4. Open and close any dialogs - does focus trap, then restore?
  5. Submit a form with errors - are error messages announced?
  6. Trigger any dynamic content update - is the change announced?

See references/screen-readers.md for NVDA/JAWS/VoiceOver commands, browse vs. forms mode, and testing scripts.


ARIA: The Rules

Rule 0: Don't use ARIA if native HTML solves it. Bad ARIA is worse than no ARIA.

Rule 1: aria-label and aria-labelledby provide the accessible name (what the element is). Rule 2: aria-describedby provides supplementary description (what it does or needs). Rule 3: aria-live="polite" for non-urgent updates; role="alert" (implicit assertive) for errors. Rule 4: Live regions must exist in the DOM on page load - inject text into them, don't inject the region itself. Rule 5: aria-hidden="true" removes from the AT tree completely. Never apply to focusable elements.

Full ARIA pattern library → references/aria-patterns.md


Visually Hidden Content

To show content to screen readers but hide it visually, use the .visually-hidden utility class - see references/common-fixes.md "The Visually Hidden Utility Class" for the canonical CSS.

Use for: skip links, supplementary link context ("Read more <span class="visually-hidden">about caching</span>"), icon button labels when aria-label is impractical for translation reasons.

Do not use for: content that sighted users need. Hiding meaningful content from one group creates disparity, not accessibility.


Colour and Contrast (WCAG AA)

Content type Minimum ratio
Body text (<18pt / 24px, and <14pt bold / 18.5px) 4.5:1
Large text (≥18pt / 24px, or ≥14pt bold / 18.5px) 3:1
UI components (borders, icons, focus rings) 3:1
Placeholder text 4.5:1
Disabled elements Exempt

Never convey information by colour alone - always pair with a shape, pattern, or text label.

Respect user colour preferences: support prefers-color-scheme, and test under Windows High Contrast / forced-colors: active rather than overriding it (never forced-color-adjust: none on meaningful content). See references/wcag-checklist.md.

Check exact foreground/background pairs from the accessibility skill directory:

python3 scripts/contrast-check.py '#333333' '#ffffff'
python3 scripts/contrast-check.py '#767676' '#ffffff' --json
python3 scripts/contrast-check.py '#949494' '#ffffff' --target large-text
python3 scripts/contrast-check.py '#949494' '#ffffff' --target ui-component

Use --target normal-text (default), large-text, ui-component, aaa-normal-text, or aaa-large-text to make the exit status follow the relevant threshold. Do not round contrast values up. A measured 4.499:1 fails a 4.5:1 requirement.

WCAG 2 AA (this table) is the sole conformance target. Its ratio maths is symmetric and ignores polarity, so it can over-rate some dark-mode pairings - if a passing pair still reads poorly on dark backgrounds, treat that as a design smell and sanity-check it with a perceptual tool (APCA). APCA is a candidate algorithm for the still-draft, undated WCAG 3 (it was even pulled from the July 2023 draft pending consensus) - a design aid only, never a compliance substitute.


Reference Files

File Contents
references/screen-readers.md NVDA/JAWS/VoiceOver commands, browse vs. forms mode, testing scripts per component type
references/aria-patterns.md ARIA roles, labelling hierarchy, live region patterns, complex widget ARIA (combobox, tabs, tree)
references/focus-management.md Modal focus trap, SPA route change focus, skip links, focus restoration patterns
references/wcag-checklist.md WCAG 2.2 AA criterion-by-criterion checklist with pass/fail examples
references/common-fixes.md Code-level fix templates for the 20 most common audit findings
scripts/contrast-check.py Deterministic WCAG contrast ratio checker for foreground/background hex pairs
tests/testcontrastcheck.py Behavioural tests for the checker (ratios, exit codes, hex parsing) - uv run --with pytest -- pytest tests/