accessibility
Skill0 starsChanged 32 days agoMITView on GitHub
Audit and fix web accessibility issues to meet WCAG 2.1 AA. Use when the user asks to make a component accessible, fix accessibility errors, add ARIA attributes, improve keyboard navigation, check color contrast, make a form accessible, fix screen reader issues, or audit a page for a11y problems.
- Installs packages
123 other projects use a version of this.
Adopted by
Most recently taken up by
- Khan/perseustheir own version, first seen Nov 9, 2026
- linx-systems/clamuitheir own version, first seen Nov 9, 2026
- Rojios/everything-claude-codetheir own version, first seen Nov 8, 2026
- ahmadvahidi/skill-atlastheir own version, first seen Nov 8, 2026
- GstMirabal/Token-Optimized-Agent-Pipelinetheir own version, first seen Nov 8, 2026
- DnsQueen/orcinus-skillstheir own version, first seen Nov 8, 2026
Used with
Projects with it also use author-contributions, tool-rename-deprecation and 10 more.
Other files people use alongside this one.
Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
MicrosoftSkillauthor-contributions
Identify all files a specific author contributed to on a branch vs its upstream, tracing code through renames. Use when asked who edited what, what code an author contributed, or to audit authorship before a merge. This skill should be run as a subagent — it performs many git operations and returns a concise table.
Also in 7 projects that use this
gitpod-ioSkilltool-rename-deprecation
Ensure renamed built-in tool references preserve backward compatibility. Use when renaming a toolReferenceName, tool set referenceName, or any tool identifier. Run on ANY change to tool registration code. Covers legacyToolReferenceFullNames for tools and legacyFullNames for tool sets.
Also in 5 projects that use this
DepressionCenterSkillproject-preferences
Apply repository-specific preferences when planning, implementing, or reviewing changes in this project.
Also in 6 projects that use this
MicrosoftSkillchat-perf
Run chat perf benchmarks and memory leak checks against the local dev build or any published VS Code version. Use when investigating chat rendering regressions, validating perf-sensitive changes to chat UI, or checking for memory leaks in the chat response pipeline.
Also in 5 projects that use this
DepressionCenterSkillcreate-media-pack
Create a coordinated project branding and media pack with three accessible design options, approved vector artwork, image exports, a branding guide, and README integration. Use when asked for a repository media pack, brand kit, or complete project visual identity.
Also in 5 projects that use this
- +7 more from microsoft
Other versions123 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 123
- microsoft/vscode★ 195ksame name
- elastic/kibana★ 21ksame name
- mozilla-mobile/firefox-ios★ 13ksame name
- midudev/preguntas-entrevista-react★ 7.8ksame name
- gitpod-io/openvscode-server★ 6.2ksame name
- posit-dev/positron★ 4.3ksame name
- legions-developer/evilcharts★ 3.2ksame name
- midudev/la-velada-web-oficial★ 1.9ksame name
- UI5/webcomponents★ 1.8ksame name
- theopenco/llmgateway★ 1.7ksame name
113 more not listed
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository68 other files it gives its agents.
- AGENTS.mdAGENTS.md
- .claude/CLAUDE.mdCLAUDE.md
- api-designSkill
- api-versioningSkill
- authSkill
- background-jobsSkill
- cachingSkill
- capacity-planningSkill
- changelogSkill
- chaos-engineeringSkill
- ci-cdSkill
- circuit-breakerSkill
- claude-best-practicesSkill
- code-commentsSkill
- code-hygieneSkill
- code-reviewSkill
- code-structureSkill
- commit-styleSkill
- concurrency-and-lockingSkill
- database-transactionsSkill
- data-consistencySkill
- debug-infra-startupSkill
- debug-sessionSkill
- demo-video-creatorSkill
- demo-video-script-creatorSkill
- dependency-injectionSkill
- dependency-updateSkill
- disk-cleanupSkill
- distributed-tracingSkill
- dockerSkill
- env-configSkill
- env-setupSkill
- error-handlingSkill
- event-driven-architectureSkill
- feature-flagsSkill
- file-storageSkill
- graceful-shutdownSkill
- idempotencySkill
- input-validationSkill
- jars-engineering-blogsmithSkill
- jars-workshop-builderSkill
- licensingSkill
- loggingSkill
- memory-and-allocationsSkill
- migrate-dbSkill
- monitoringSkill
- multi-tenancySkill
- notificationsSkill
- openapiSkill
- paginationSkill
- perf-profileSkill
- pr-descriptionSkill
- query-optimizationSkill
- rate-limitingSkill
- refactorSkill
- releaseSkill
- runbook-writerSkill
- searchSkill
- secrets-auditSkill
- simplifySkill
- The first 60 shown.
The file
Show its rules and text
We split this skill into the rules it gives an agent
19 rules. 0 are common, 14 are distinctive, and 5 are very specific to this project.
0
Common
Most of the 112 edited versions we read keep these.
14
Distinctive
This author's own choices. Worth a look.
5
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 9
Read the actual markup before suggesting fixes.
- Distinctive: line 14
Read the component before suggesting changes: Never propose ARIA attributes without seeing the existing HTML structure.
- Distinctive: line 18
ARIA is a patch, not a replacement: Use it only when no semantic HTML element exists for the job.
- Distinctive: line 20
Every fix must be verified: Run the automated tool after changes and note what still needs manual testing.
- Distinctive: line 29
Run automated checks before touching code:
- Distinctive: line 50
Every interactive element must be reachable and operable with a keyboard alone.
- Distinctive: line 62
If you must use a non-native element:
- Distinctive: line 77
When a modal opens, focus must move into it and be trapped until it closes:
- Distinctive: line 106
When the modal closes, return focus to the element that opened it.
- Very specific: line 110
Add a skip link as the first element in <body> so keyboard users can jump past navigation:
- Distinctive: line 134
Use ARIA only when a native element doesn't exist for the pattern.
- Distinctive: line 138
Every interactive element needs an accessible name:
- Very specific: line 158
Never use placeholder as the only label — it disappears when the user types and has poor contrast in most browsers.
- Distinctive: line 163
Use live regions to announce dynamic content to screen readers:
- Very specific: line 177
Don't overuse assertive — it interrupts whatever the screen reader is currently saying.
- Very specific: line 181
Every page must have one <main>.
- Very specific: line 191
If there are multiple <nav> or <section> elements, distinguish them with aria-label.
- Distinctive: line 259
Check contrast without writing code:
- Distinctive: line 268
Never convey information with color alone — add a pattern, icon, or text label alongside.
“Common” is measured: kept by at least 6 in 10 of the 112 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.
Files
Accessibility
Find and fix real barriers that prevent people from using the UI — not just checklist items. Read the actual markup before suggesting fixes. Automated tools catch ~30% of issues; the rest require reading the code with intent.
Ground rules
- Read the component before suggesting changes. Never propose ARIA attributes without seeing the existing HTML structure.
- Use semantic HTML first. A
<button>is better than<div role="button">. Native elements bring keyboard handling, focus management, and ARIA roles for free. - ARIA is a patch, not a replacement. Use it only when no semantic HTML element exists for the job. Wrong ARIA is worse than no ARIA.
- Every fix must be verified. Run the automated tool after changes and note what still needs manual testing.
- Full WCAG compliance requires manual testing with a real screen reader and keyboard. Automated tools and code review are not sufficient on their own.
Step 0: Audit first
Run automated checks before touching code:
# axe-core CLI — best automated coverage
npx axe-cli https://localhost:3000/page --save report.json
# Or with Playwright (in CI)
npm install --save-dev @axe-core/playwright
# See: https://github.com/dequelabs/axe-core-npm/tree/develop/packages/playwright
# Lighthouse (built into Chrome DevTools → Lighthouse tab → Accessibility)
# Or CLI:
npx lighthouse https://localhost:3000/page --only-categories=accessibility --output=jsonTriage the output: fix critical and serious violations first, then moderate.
Keyboard navigation
Every interactive element must be reachable and operable with a keyboard alone.
Focus management
<!-- Bad — div swallows all keyboard events -->
<div onclick="handleClick()">Submit</div>
<!-- Good — native button is focusable, activates on Enter and Space -->
<button type="button" onclick="handleClick()">Submit</button>If you must use a non-native element:
<div
role="button"
tabindex="0"
onclick="handleClick()"
onkeydown="if(event.key==='Enter'||event.key===' ') handleClick()"
>
Submit
</div>Focus trap in modals
When a modal opens, focus must move into it and be trapped until it closes:
// Move focus to the modal on open
modal.querySelector<HTMLElement>('[autofocus], h2, button')?.focus();
// Trap: intercept Tab and Shift+Tab to cycle within the modal
function trapFocus(event: KeyboardEvent, container: HTMLElement) {
const focusable = Array.from(
container.querySelectorAll<HTMLElement>(
'a[href], button:not([disabled]), input, select, textarea, [tabindex]:not([tabindex="-1"])'
)
);
const first = focusable[0];
const last = focusable[focusable.length - 1];
if (event.key === 'Tab') {
if (event.shiftKey && document.activeElement === first) {
event.preventDefault();
last.focus();
} else if (!event.shiftKey && document.activeElement === last) {
event.preventDefault();
first.focus();
}
}
if (event.key === 'Escape') closeModal();
}When the modal closes, return focus to the element that opened it.
Skip link
Add a skip link as the first element in <body> so keyboard users can jump past navigation:
<a href="#main-content" class="skip-link">Skip to main content</a>
<!-- visually hidden until focused -->
<main id="main-content" tabindex="-1">...</main>.skip-link {
position: absolute;
top: -100%;
left: 0;
}
.skip-link:focus {
top: 0;
}ARIA
Use ARIA only when a native element doesn't exist for the pattern.
Labels
Every interactive element needs an accessible name:
<!-- Icon-only button — no visible text -->
<button type="button" aria-label="Close dialog">
<svg aria-hidden="true" focusable="false">...</svg>
</button>
<!-- Input with a visible label -->
<label for="email">Email address</label>
<input id="email" type="email" />
<!-- Input with no visible label (search bars) -->
<input type="search" aria-label="Search products" />
<!-- Labelled by another element -->
<h2 id="dialog-title">Confirm deletion</h2>
<div role="dialog" aria-labelledby="dialog-title" aria-modal="true">...</div>Never use placeholder as the only label — it disappears when the user types and has
poor contrast in most browsers.
Live regions
Use live regions to announce dynamic content to screen readers:
<!-- Announce status messages without moving focus -->
<div role="status" aria-live="polite" aria-atomic="true">
<!-- inject text here when something changes: "3 results found" -->
</div>
<!-- For urgent alerts (errors, destructive confirmations) -->
<div role="alert" aria-live="assertive">
<!-- inject error messages here -->
</div>Don't overuse assertive — it interrupts whatever the screen reader is currently saying.
Landmark roles
Every page must have one <main>. Use landmarks so screen reader users can jump between sections:
<header>...</header> <!-- banner landmark -->
<nav aria-label="Primary">...</nav>
<main id="main-content">...</main>
<aside aria-label="Related articles">...</aside>
<footer>...</footer> <!-- contentinfo landmark -->If there are multiple <nav> or <section> elements, distinguish them with aria-label.
State
Reflect interactive state in ARIA when CSS alone doesn't convey it:
<!-- Accordion -->
<button aria-expanded="false" aria-controls="section-1">Section 1</button>
<div id="section-1" hidden>...</div>
<!-- Toggle button -->
<button aria-pressed="false">Mute</button>
<!-- Disabled (prefer native disabled attribute on form elements) -->
<button disabled>Save</button>
<!-- For non-native elements: -->
<div role="button" aria-disabled="true" tabindex="-1">Save</div>Forms
<!-- Every input must have a label -->
<div>
<label for="name">Full name <span aria-hidden="true">*</span></label>
<input
id="name"
type="text"
autocomplete="name"
required
aria-required="true"
aria-describedby="name-error"
/>
<!-- Error — only rendered when invalid -->
<span id="name-error" role="alert" aria-live="polite">
Full name is required.
</span>
</div>
<!-- Group related inputs -->
<fieldset>
<legend>Notification preferences</legend>
<label><input type="checkbox" name="email-notif" /> Email</label>
<label><input type="checkbox" name="sms-notif" /> SMS</label>
</fieldset>Error messages must be:
- Programmatically associated with the field (
aria-describedby) - Injected into a live region or announced via
role="alert" - Descriptive: "Email is required" not just "Required"
Color and contrast
WCAG 2.1 AA minimums:
| Text type | Minimum contrast ratio |
| Normal text (< 18pt / 14pt bold) | 4.5 : 1 |
| Large text (≥ 18pt / 14pt bold) | 3 : 1 |
| UI components and icons | 3 : 1 |
| Decorative elements | No requirement |
Check contrast without writing code:
# CLI check (give it a foreground and background hex)
npx color-contrast-checker "#1a1a1a" "#f5f5f5"
# Or use the browser DevTools → Accessibility panel → inspect element contrastNever convey information with color alone — add a pattern, icon, or text label alongside.
Images and media
<!-- Informative image — describe what it conveys -->
<img src="chart.png" alt="Bar chart showing monthly sales growth of 12% in Q4 2024" />
<!-- Decorative image — hide from assistive technology -->
<img src="divider.png" alt="" role="presentation" />
<!-- SVG inline — title + desc for complex graphics -->
<svg role="img" aria-labelledby="chart-title chart-desc">
<title id="chart-title">Monthly revenue</title>
<desc id="chart-desc">A line chart showing revenue growing from $10k to $45k over 6 months.</desc>
...
</svg>
<!-- Video — captions required, audio description if visuals convey meaning -->
<video controls>
<source src="demo.mp4" type="video/mp4" />
<track kind="captions" src="demo.vtt" srclang="en" label="English" default />
</video>Common violations and fixes
| Violation | Fix |
Interactive <div> or <span> | Replace with <button> or <a href> |
<img> missing alt | Add alt="" for decorative, descriptive text for informative |
| Form input with no label | Add <label for="id"> or aria-label |
| Color contrast below 4.5:1 | Darken text or lighten/darken background |
| Modal doesn't trap focus | Implement focus trap; return focus on close |
| No skip link | Add <a href="#main-content">Skip to main content</a> |
aria-label on a non-interactive element | Remove it; ARIA labels are for interactive elements |
Multiple <h1> elements | One <h1> per page; use <h2>–<h6> for hierarchy |
Heading levels skipped (<h1> → <h3>) | Fix the hierarchy; headings must not skip levels |
<table> without <th> | Add <th scope="col"> or <th scope="row"> headers |
role="button" missing keyboard handler | Add onkeydown for Enter and Space |
aria-hidden="true" on focusable content | Remove aria-hidden or add tabindex="-1" |
Focus indicator removed with outline: none | Restore :focus-visible styles |
Checklist
- Automated scan run (
axe-clior Lighthouse) with no critical/serious violations - All images have
alttext (descriptive or emptyalt=""for decorative) - All form inputs have a visible, associated
<label> - Error messages are associated with inputs via
aria-describedby - Every interactive element is reachable and operable by keyboard
- Modals trap focus and return it on close
- Skip link present as the first focusable element
- Heading hierarchy is sequential with no skipped levels
- Color contrast meets 4.5:1 for text, 3:1 for UI components
- No information conveyed by color alone
- Dynamic content updates announced via live regions
- Focus indicator visible (
:focus-visiblenot suppressed) - Note to user: full WCAG compliance requires manual testing with a screen reader (NVDA, VoiceOver, or JAWS)
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
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.

