{"id":"0c918c28-14f4-4d73-8ffd-82851b7d886b","shortId":"fuDVLY","kind":"skill","title":"Accessibility Audit Helper","tagline":"Reviews UI code and components for WCAG 2.1 accessibility violations and provides specific fixes.","description":"# Accessibility Audit Helper\n\n## What this skill does\n\nThis skill directs the agent to review HTML, JSX, or React component code for WCAG 2.1 accessibility violations. It checks for missing alt text, improper heading hierarchy, ARIA misuse, keyboard trap risks, color contrast hints, missing focus indicators, and more. Every finding is categorized by severity with a concrete before/after code fix included.\n\nUse this before shipping any UI feature, during code review, or as a regular accessibility sweep of your component library.\n\n## How to use\n\n### Claude Code / Cline\n\nCopy this file to `.agents/skills/accessibility-audit-helper/SKILL.md` in your project root.\n\nThen share the component or page code and ask:\n- *\"Run an accessibility audit on `src/components/Modal.tsx` using the Accessibility Audit Helper skill.\"*\n- *\"Use the Accessibility Audit Helper skill to check this form for a11y issues.\"*\n\nPaste the component code directly or provide a file path for the agent to read.\n\n### Cursor\n\nAdd the \"Prompt / Instructions\" section to your `.cursorrules` file. Open the component you want audited and ask Cursor to run an accessibility audit.\n\n### Codex\n\nPaste the component or page HTML/JSX into the chat along with the instructions below.\n\n## The Prompt / Instructions for the Agent\n\nWhen asked to audit UI code for accessibility, follow these steps:\n\n1. **Read the full component or file.** If it references child components or imports, note them but focus the audit on the provided code.\n\n2. **Check each of these categories systematically:**\n\n   **Images and Media**\n   - All `<img>` elements must have an `alt` attribute; decorative images use `alt=\"\"`\n   - Icons used as buttons or links must have an `aria-label` or `aria-labelledby`\n   - SVGs used for meaning must have a `<title>` or `aria-label`; decorative SVGs need `aria-hidden=\"true\"`\n\n   **Heading Hierarchy**\n   - Headings must not skip levels (e.g., H1 → H3 with no H2)\n   - Each page should have exactly one `<h1>`\n   - Headings must describe the section content, not just style large text\n\n   **Interactive Elements**\n   - All buttons must have visible, descriptive text or an `aria-label`\n   - Links must have descriptive text — \"Click here\" or \"Read more\" alone are violations\n   - Custom interactive elements (divs/spans with click handlers) must have `role`, `tabIndex={0}`, and keyboard event handlers (`onKeyDown` for Enter/Space)\n   - `<button>` elements must not be nested inside `<a>` tags, and vice versa\n\n   **Forms**\n   - Every form input must have an associated `<label>` (via `htmlFor`/`id`, `aria-label`, or `aria-labelledby`)\n   - Required fields must be indicated (not just by color) — use `aria-required=\"true\"` or `required`\n   - Error messages must be programmatically associated with the field using `aria-describedby`\n   - Form groups (e.g., radio buttons) should use `<fieldset>` and `<legend>`\n\n   **Keyboard and Focus**\n   - Interactive elements must be reachable via keyboard (Tab key)\n   - No positive `tabIndex` values (1, 2, 3...) — these break natural tab order\n   - Modal dialogs must trap focus within them when open and return focus when closed\n   - Menus and dropdowns must be navigable with arrow keys and closable with Escape\n   - Focus must never disappear (no `outline: none` without a replacement focus style)\n\n   **ARIA**\n   - ARIA roles must be used correctly — do not add `role=\"button\"` to an already-interactive `<button>`\n   - `aria-hidden=\"true\"` must not be applied to elements that contain focusable children\n   - Live regions (`aria-live`) should be used for dynamically updated content (status messages, alerts)\n   - Do not use `aria-label` on non-interactive elements unless there's a semantic reason\n\n   **Color and Contrast (static analysis)**\n   - Flag any inline color styles or Tailwind text/background combinations that are likely to fail WCAG AA contrast (4.5:1 for normal text, 3:1 for large text)\n   - Flag information conveyed by color alone (red = error) without a non-color indicator\n\n   **Document Structure**\n   - Pages should have a `<main>` landmark, a `<header>`, and a `<nav>` (when applicable)\n   - Navigation landmarks should have `aria-label` when multiple `<nav>` elements exist on a page\n\n3. **Categorize every finding by WCAG severity:**\n   - **Critical** (WCAG Level A) — completely blocks access for assistive technology users; must fix before shipping\n   - **Serious** (WCAG Level AA) — significantly degrades the experience; should fix before shipping\n   - **Moderate** (best practice / Level AAA) — improves experience; fix when possible\n\n4. **For every finding, provide:**\n   - The WCAG criterion violated (e.g., WCAG 2.1 SC 1.1.1)\n   - A plain-English explanation of the problem\n   - The specific line or element with the violation\n   - A concrete code fix (before/after)\n\n5. **Output format:**\n\n```\n## Accessibility Audit Results\n\n### Summary\n[X] Critical violations · [Y] Serious violations · [Z] Moderate violations\n\n---\n\n### Critical Violations\n\n#### 1. [Violation title] — WCAG 2.1 SC [X.X.X]\n**Problem:** [Plain English explanation]\n**Location:** [Element / line description]\n\n**Before:**\n```[lang]\n[problematic code]\n```\n\n**Fix:**\n```[lang]\n[corrected code]\n```\n\n---\n[repeat for each finding, grouped by severity]\n\n### Passed Checks\n- [List checks that passed cleanly]\n```\n\n## Example\n\n**Input to Agent:**\n> \"Use the Accessibility Audit Helper skill on this component:\n>\n> ```tsx\n> export function SearchBar({ onSearch }) {\n>   return (\n>     <div>\n>       <input type=\"text\" placeholder=\"Search...\" onChange={e => onSearch(e.target.value)} />\n>       <div onClick={onSearch} style={{ cursor: 'pointer' }}>\n>         <svg width=\"16\" height=\"16\"><path d=\"M...\"/></svg>\n>       </div>\n>     </div>\n>   );\n> }\n> ```\"\n\n**Output from Agent:**\n> ## Accessibility Audit Results\n>\n> ### Summary\n> 2 Critical violations · 1 Serious violation · 0 Moderate violations\n>\n> ---\n>\n> ### Critical Violations\n>\n> #### 1. Input has no label — WCAG 2.1 SC 1.3.1\n> **Problem:** The text input has no associated label. Screen readers will only announce \"edit text\" with no context about its purpose.\n> **Location:** `<input type=\"text\" placeholder=\"Search...\">`\n>\n> **Before:**\n> ```tsx\n> <input type=\"text\" placeholder=\"Search...\" onChange={...} />\n> ```\n>\n> **Fix:**\n> ```tsx\n> <label htmlFor=\"search-input\" className=\"sr-only\">Search</label>\n> <input id=\"search-input\" type=\"text\" placeholder=\"Search...\" onChange={...} />\n> ```\n>\n> #### 2. SVG icon has no accessible name — WCAG 2.1 SC 1.1.1\n> **Problem:** The SVG is inside a clickable element but has no title or aria-label. Screen readers cannot determine its purpose.\n>\n> **Before:**\n> ```tsx\n> <svg width=\"16\" height=\"16\"><path d=\"M...\"/></svg>\n> ```\n>\n> **Fix:**\n> ```tsx\n> <svg width=\"16\" height=\"16\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M...\"/></svg>\n> ```\n> (The parent button carries the accessible name; hide the SVG from the a11y tree.)\n>\n> ---\n>\n> ### Serious Violations\n>\n> #### 3. Clickable div is not keyboard accessible — WCAG 2.1 SC 2.1.1\n> **Problem:** A `<div>` with an `onClick` handler is not reachable or activatable via keyboard.\n>\n> **Before:**\n> ```tsx\n> <div onClick={onSearch} style={{ cursor: 'pointer' }}>...</div>\n> ```\n>\n> **Fix:**\n> ```tsx\n> <button type=\"button\" onClick={onSearch} aria-label=\"Search\">...</button>\n> ```\n>\n> ---\n>\n> ### Passed Checks\n> - No positive tabIndex values\n> - No aria-hidden on focusable children\n> - No heading hierarchy issues","tags":["accessibility","audit","helper","openagentskills","notysoty","agent-skills","claude","claude-code","claude-skills","cline","cursor","llm"],"capabilities":["skill","source-notysoty","skill-accessibility-audit-helper","topic-agent-skills","topic-claude","topic-claude-code","topic-claude-skills","topic-cline","topic-cursor","topic-llm","topic-llm-skills","topic-skills"],"categories":["openagentskills"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/Notysoty/openagentskills/accessibility-audit-helper","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add Notysoty/openagentskills","source_repo":"https://github.com/Notysoty/openagentskills","install_from":"skills.sh"}},"qualityScore":"0.454","qualityRationale":"deterministic score 0.45 from registry signals: · indexed on github topic:agent-skills · 8 github stars · SKILL.md body (7,499 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-05-18T19:13:19.718Z","embedding":null,"createdAt":"2026-05-18T13:20:39.812Z","updatedAt":"2026-05-18T19:13:19.718Z","lastSeenAt":"2026-05-18T19:13:19.718Z","tsv":"'0':365,817 '1':218,454,587,592,733,814,822 '1.1.1':693,884 '1.3.1':830 '2':242,455,811,874 '2.1':11,40,691,737,828,882,935 '2.1.1':937 '3':456,591,636,927 '4':680 '4.5':586 '5':715 'a11y':145,923 'aa':584,661 'aaa':674 'access':1,12,18,41,92,124,130,136,184,214,649,718,776,807,879,916,933 'activat':948 'add':163,510 'agent':29,159,206,773,806 'agents/skills/accessibility-audit-helper/skill.md':108 'alert':546 'alon':351,601 'along':196 'alreadi':516 'already-interact':515 'alt':47,257,262 'analysi':568 'announc':843 'appli':525 'applic':621 'aria':52,273,277,288,294,339,395,399,412,428,501,502,519,535,551,627,899,967,978 'aria-describedbi':427 'aria-hidden':293,518,977 'aria-l':534 'aria-label':272,287,338,394,550,626,898,966 'aria-labelledbi':276,398 'aria-requir':411 'arrow':483 'ask':121,179,208 'assist':651 'associ':390,422,837 'attribut':258 'audit':2,19,125,131,137,177,185,210,237,719,777,808 'before/after':74,714 'best':671 'block':648 'break':458 'button':266,330,434,512,913,961,963 'cannot':903 'carri':914 'categor':68,637 'categori':247 'chat':195 'check':44,141,243,764,766,971 'child':228 'children':531,982 'claud':101 'clean':769 'click':346,359 'clickabl':891,928 'cline':103 'closabl':486 'close':475 'code':6,37,75,86,102,119,150,212,241,712,751,755 'codex':186 'color':57,409,564,572,600,608 'combin':577 'complet':647 'compon':8,36,96,116,149,174,189,222,229,782 'concret':73,711 'contain':529 'content':321,543 'context':848 'contrast':58,566,585 'convey':598 'copi':104 'correct':507,754 'criterion':687 'critic':643,723,731,812,820 'cursor':162,180,802,957 'cursorrul':170 'custom':354 'decor':259,290 'degrad':663 'describ':318 'describedbi':429 'descript':334,344,747 'determin':904 'dialog':463 'direct':27,151 'disappear':492 'div':798,929,953 'divs/spans':357 'document':610 'dropdown':478 'dynam':541 'e':795 'e.g':304,432,689 'e.target.value':797 'edit':844 'element':253,328,356,373,442,527,557,631,706,745,892 'english':697,742 'enter/space':372 'error':417,603 'escap':488 'event':368 'everi':65,384,638,682 'exact':314 'exampl':770 'exist':632 'experi':665,676 'explan':698,743 'export':784 'fail':582 'featur':84 'field':402,425 'file':106,155,171,224 'find':66,639,683,759 'fix':17,76,655,667,677,713,752,861,909,959 'flag':569,596 'focus':61,235,440,466,473,489,499,530,981 'follow':215 'form':143,383,385,430 'format':717 'full':221 'function':785 'group':431,760 'h1':305 'h2':309 'h3':306 'handler':360,369,943 'head':50,297,299,316,984 'helper':3,20,132,138,778 'hidden':295,520,979 'hide':918 'hierarchi':51,298,985 'hint':59 'html':32 'html/jsx':192 'htmlfor':392 'icon':263,876 'id':393,865 'imag':249,260 'import':231 'improp':49 'improv':675 'includ':77 'indic':62,405,609 'inform':597 'inlin':571 'input':386,771,789,823,834,855,864,868 'insid':378,889 'instruct':166,199,203 'interact':327,355,441,517,556 'issu':146,986 'jsx':33 'key':449,484 'keyboard':54,367,438,447,932,950 'label':274,289,340,396,552,628,826,838,900,968 'labelledbi':278,400 'landmark':616,623 'lang':749,753 'larg':325,594 'level':303,645,660,673 'librari':97 'like':580 'line':704,746 'link':268,341 'list':765 'live':532,536 'locat':744,852 'mean':282 'media':251 'menus':476 'messag':418,545 'miss':46,60 'misus':53 'modal':462 'moder':670,729,818 'multipl':630 'must':254,269,283,300,317,331,342,361,374,387,403,419,443,464,479,490,504,522,654 'name':880,917 'natur':459 'navig':481,622 'need':292 'nest':377 'never':491 'non':555,607 'non-color':606 'non-interact':554 'none':495 'normal':589 'note':232 'onchang':794,860,873 'onclick':799,942,954,964 'one':315 'onkeydown':370 'onsearch':787,796,800,955,965 'open':172,470 'order':461 'outlin':494 'output':716,804 'page':118,191,311,612,635 'parent':912 'pass':763,768,970 'past':147,187 'path':156 'placehold':792,858,871 'plain':696,741 'plain-english':695 'pointer':803,958 'posit':451,973 'possibl':679 'practic':672 'problem':701,740,831,885,938 'problemat':750 'programmat':421 'project':111 'prompt':165,202 'provid':15,153,240,684 'purpos':851,906 'radio':433 'reachabl':445,946 'react':35 'read':161,219,349 'reader':840,902 'reason':563 'red':602 'refer':227 'region':533 'regular':91 'repeat':756 'replac':498 'requir':401,413,416 'result':720,809 'return':472,788 'review':4,31,87 'risk':56 'role':363,503,511 'root':112 'run':122,182 'sc':692,738,829,883,936 'screen':839,901 'search':793,859,863,867,872,969 'search-input':866 'searchbar':786 'section':167,320 'semant':562 'serious':658,726,815,925 'sever':70,642,762 'share':114 'ship':81,657,669 'signific':662 'skill':23,26,133,139,779 'skill-accessibility-audit-helper' 'skip':302 'source-notysoty' 'specif':16,703 'src/components/modal.tsx':127 'static':567 'status':544 'step':217 'structur':611 'style':324,500,573,801,956 'summari':721,810 'svg':875,887,920 'svgs':279,291 'sweep':93 'systemat':248 'tab':448,460 'tabindex':364,452,974 'tag':379 'tailwind':575 'technolog':652 'text':48,326,335,345,590,595,791,833,845,857,870 'text/background':576 'titl':735,896 'topic-agent-skills' 'topic-claude' 'topic-claude-code' 'topic-claude-skills' 'topic-cline' 'topic-cursor' 'topic-llm' 'topic-llm-skills' 'topic-skills' 'trap':55,465 'tree':924 'true':296,414,521 'tsx':783,854,862,908,910,952,960 'type':790,856,869,962 'ui':5,83,211 'unless':558 'updat':542 'use':78,100,128,134,261,264,280,410,426,436,506,539,549,774 'user':653 'valu':453,975 'versa':382 'via':391,446,949 'vice':381 'violat':13,42,353,688,709,724,727,730,732,734,813,816,819,821,926 'visibl':333 'want':176 'wcag':10,39,583,641,644,659,686,690,736,827,881,934 'within':467 'without':496,604 'x':722 'x.x.x':739 'y':725 'z':728","prices":[{"id":"13e8506b-2f46-4f38-98d9-0d0a8fa751c4","listingId":"0c918c28-14f4-4d73-8ffd-82851b7d886b","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"Notysoty","category":"openagentskills","install_from":"skills.sh"},"createdAt":"2026-05-18T13:20:39.812Z"}],"sources":[{"listingId":"0c918c28-14f4-4d73-8ffd-82851b7d886b","source":"github","sourceId":"Notysoty/openagentskills/accessibility-audit-helper","sourceUrl":"https://github.com/Notysoty/openagentskills/tree/main/skills/accessibility-audit-helper","isPrimary":false,"firstSeenAt":"2026-05-18T13:20:39.812Z","lastSeenAt":"2026-05-18T19:13:19.718Z"}],"details":{"listingId":"0c918c28-14f4-4d73-8ffd-82851b7d886b","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"Notysoty","slug":"accessibility-audit-helper","github":{"repo":"Notysoty/openagentskills","stars":8,"topics":["agent-skills","claude","claude-code","claude-skills","cline","cursor","llm","llm-skills","skills"],"license":"mit","html_url":"https://github.com/Notysoty/openagentskills","pushed_at":"2026-03-28T06:50:19Z","description":"A  community-driven library of reusable AI agent skills for Claude Code, Cursor, Codex, Cline, and more.","skill_md_sha":"9950e580c08b5ebfb8ed461540b352a6ced057d2","skill_md_path":"skills/accessibility-audit-helper/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/Notysoty/openagentskills/tree/main/skills/accessibility-audit-helper"},"layout":"multi","source":"github","category":"openagentskills","frontmatter":{"name":"Accessibility Audit Helper","description":"Reviews UI code and components for WCAG 2.1 accessibility violations and provides specific fixes."},"skills_sh_url":"https://skills.sh/Notysoty/openagentskills/accessibility-audit-helper"},"updatedAt":"2026-05-18T19:13:19.718Z"}}