better-accessibility
Reviews and fixes keyboard and focus behavior, ARIA, accessible names, forms, screen-reader announcements, motion and zoom in your project against WCAG 2.2.
Skill by transitive-bullshit
Install
Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.
npx agentmarket install skill/transitive-bullshit-better-accessibility
Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.
Get the weekly diff
The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.
About
Reviews
Write a reviewNo reviews yet. Installed it? Reviews come from verified installers only. How reviews work
Permissions
What this skill can do and what it asks for, from its SKILL.md and code. Checked Oct 26, 2026.
- Tools
- No tools found
- Secrets
- None asked for
- Install scripts
- None found
Network hosts it talks to 1
codeload.github.com· found in install command
Files it touches
~/.claude/skills/better-accessibility
What's inside
- Skill name
better-accessibility- Description
- Reviews and fixes keyboard and focus behavior, ARIA, accessible names, forms, screen-reader announcements, motion and zoom in your project against WCAG 2.2.
- License
- MIT
- Instructions
- 137 lines in SKILL.md · view on GitHub
Files (8)
- SKILL.md
- openai.yaml · agents/
- focus-and-keyboard.md
- forms.md
- hit-areas.md
- motion-and-zoom.md
- screen-readers.md
- semantics-and-aria.md
SKILL.md (first lines)
# Accessibility
This skill reviews and fixes semantics, keyboard and focus behavior, accessible names, forms, announcements, motion and zoom. It reports each failure against the WCAG criterion it breaks and writes the fix in the project's styling system.
Reviewing means two walks. Keyboard-only, where every flow completes without a mouse. Then screen-reader, where every control announces a name, a role and its state. When unsure, take the platform default over a custom rebuild, and remove ARIA rather than add it.
Contrast measurement and color fixes belong to `better-colors`. Text sizing, iOS input zoom and language metadata belong to `better-typography`. Spacing between targets and spatial RTL belong to `better-layout`. Label, error and alt-text wording belong to `better-writing`. Animation recipes, hover styling and scroll containment belong to `better-ui`.
## Criteria, not conventions
A finding cites a WCAG 2.2 Level A or AA criterion by number, or a concrete task an assistive-technology user cannot complete. Everything else is a recommendation and never `HIGH`. That covers AAA criteria, APG conventions, the one-`<h1>` and no-skipped-levels outline and the 44px and 40px targets. The criterion thresholds below are exact. The larger targets are heuristics, so keep an established, usable density.
## Native elements first
The first rule of ARIA: don't use ARIA when a native element exists. `<button>` for actions, `<a href>` for navigation, never `<div onClick>`. A real link must support Cmd/Ctrl/middle-click. See [semantics-and-aria.md](semantics-and-aria.md) for landmarks and button-vs-link.
## Disabled means unavailable
Use native `disabled` when a control is genuinely unavailable. Reach for `aria-disabled="true"` only when it should stay focusable, then block pointer, keyboard and form behavior in code and style the state explicitly. The rules are in [semantics-and-aria.md](semantics-and-aria.md).
## Visible focus rings
Style `:focus-visible`, not bare `:focus`. Keyboard users get a ring and mouse users usually don't. Prefer the browser's unmodified indicator.
A custom ring needs a project focus token or another explicit color. It must reach 3:1 against every adjacent color it crosses, `currentColor` included, under 1.4.11. A `2px` solid perimeter with a 3:1 change of contrast is the 2.4.13 AAA target. Never use `outline: none` without a verified replacement, and preserve system colors in forced-colors mode.
A focused element must never sit fully hidden behind a sticky header, footer or banner (2.4.11). Give the scroller `scroll-padding-top` equal to the sticky header's height. Recipes are in [focus-and-keyboard.md](focus-and-keyboard.md).
## Full keyboard support
Every pointer interaction needs a keyboard path. Follow the ARIA APG patterns: Escape closes overlays, arrow keys move within composite widgets, Tab moves between widgets, Enter and Space activate buttons.
Use only `tabindex="0"` to join the natural tab order and `tabindex="-1"` for programmatic focus. Positive values break that order. Composite widgets use roving tabindex, where the active item is `0` and every other is `-1`. Where focus must stay in an input, as in a combobox, use `aria-activedescendant` instead. Key maps per widget are in [focus-and-keyboard.md](focus-and-keyboard.md).
## Trap and restore focus
Prefer `<dialog>` opened with `showModal()`, which makes the background inert and handles Escape. A custom overlay sets `inert` on the background, `role="dialog"` and `aria-modal="true"` on itself. Either way, move focus inside on open and return it to the trigger on close.
Client-side route changes reset nothing. Update `document.title` and move focus to the new view's `<h1>` or `<main>`. Both recipes are in [focus-and-keyboard.md](focus-and-keyboard.md).
## Minimum hit area
WCAG 2.5.8's Level AA baseline is a 24×24 CSS-pixel target, or one of its exceptions. Aim for 44×44px on touch and 40×40px on desktop where density permits. Extend with a pseudo-element when the visible element should stay smaller.
Never let extended hit areas overlap. Give decorative layers `pointer-events: none`, so a glow never swallows the clicks meant for the control beneath it.
Every drag interaction needs a single-pointer alternative, such as buttons or a menu that reorder or move the same item (2.5.7). Sizes, exceptions and collision rules are in [hit-areas.md](hit-areas.md).
## Label and type every control
Every input gets a `<label for>` or a wrapping `<label>`. A placeholder is never a label. Label and control share one hit target, with no dead zone between a checkbox and its text.
Add a valid `autocomplete` token and a descriptive `name` attribute, plus the `type` and `inputmode` that summon the right keyboard. Never block paste; users paste passwords and one-time codes. See [forms.md](forms.md).
## Errors that announce
Validate on submit, never by disabling submit until the form is valid. Mark failing fields `aria-invalid="true"`, point `aria-describedby` at the inline error text and focus the first invalid field. Submit behavior while the request runs is in [forms.md](forms.md).
## Accessible names everywhere
Icon-only buttons need a descriptive `aria-label`. Visible label text must appear in the accessible name. Decorative elements get `aria-hidden="true"`, never on a focusable element.
## Don't rely on color alone
Status needs a redundant cue: an icon, text or an underline alongside the color (1.4.1).
This skill decides which contrast requirement applies:
| Criterion | Applies to | Minimum |
| --- | --- | --- |
| 1.4.3 AA | Text | 4.5:1 |
| 1.4.3 AA | Large text, at least `24px` or `18.67px` bold | 3:1 |
| 1.4.11 AA | UI component boundaries, states and meaningful graphics | 3:1 |
Inactive controls and logos are exempt. Use `better-colors` to measure the rendered pair. When it fails, report the pair and the criterion it misses, and leave the colors alone unless asked.
## Honor prefers-reduced-motion
Wrap motion in `@media (prefers-reduced-motion: no-preference)` so it is opt-in. Under reduced motion, replace slides and scales with opacity crossfades, and kill parallax and autoplay entirely. See [motion-and-zoom.md](motion-and-zoom.md).
## Nothing the user needs runs on a timer
Anything moving, blinking or updating on its own for more than 5 seconds needs a visible pause control (2.2.2). Toasts carrying an action or an error stay until dismissed. The rules are in [motion-and-zoom.md](motion-and-zoom.md).
## Announce dynamic content
Three mechanisms, three jobs. `aria-describedby` carries field-specific validation. A polite live region (`role="status"`) carries non-urgent updates not tied to a control, such as toasts and result counts. `role="alert"` carries urgent untied errors and nothing else.
Repeated polite announcements need a stable empty region rendered before its text updates. Dynamically inserted alerts vary in support, so test them on the screen readers you target. See [screen-readers.md](screen-readers.md).
## Alt text by purpose
Decorative images get `alt=""`. Informative images describe the meaning. Functional images describe the action, never the picture. The full table is in [screen-readers.md](screen-readers.md).
## Structure is navigation
Use headings that describe their sections and form a coherent outline. Expose one visible primary `<main>` landmark. When repeated navigation or chrome precedes it, make a "Skip to content" link the first focusable element. Anchored headings get `scroll-margin-top`.
## Survive zoom and text resize
Text must survive 200% resize (1.4.4), and the page must reflow at 320px width without horizontal scrolling (1.4.10). Text containers take `min-height`, not `height`, and `better-layout` owns the rest of that fix. Never set `maximum-scale=1` or `user-scalable=no` in the viewport meta. iOS input zoom is fixed with `better-typography`'s `16px` rule instead.
## Before you finish
| Pattern | Fix |
| --- | --- |
| `outline: none` or `outline-none` with no `focus-visible` replacement nearby | Restore the browser ring or add a verified custom one |
| `<div onClick` or `<span onClick` | Use `<button>`, or `<a href>` when it navigates |
| `role="button"` or `role="tab"` with no `onKeyDown` | Use the native element, or implement the APG key map |
| `tabIndex={1}` or any positive `tabindex` | Fix the DOM order and use `0` |
| `disabled={!isValid}` on a submit button | Keep it enabled and validate on submit |
| `{msg && <div role="status">`, region mounted with its text | Render the empty region first and update its text |
| `aria-live="assertive"` on a success toast | `role="status"` |
| `<img` with no `alt` attribute | `alt=""` if decorative, otherwise describe the purpose |
| `aria-label` whose text omits the visible label | Start the name with the visible text |
| `aria-hidden` on an ancestor of a button, link or input | Remove it, or make the subtree inert |
| `maximum-scale=1` or `user-scalable=no` | Remove it |
| `position: sticky` header with no `scroll-padding-top` on the scroller | Pad the scroller by the header height |
| Tooltip on a natively `disabled` control | Text beside it, or `aria-disabled` so it stays focusable |From transitive-bullshit/skills, MIT.
More from transitive-bullshit/skills
- 0.606score
better-writing
transitive-bullshit
Writes and reviews your interface copy, from labels and errors to empty states and confirmations, so it matches your product's voice and tells people what to…
SkillAFreshness: A★ 4Claude Code +9 - 0.606score
better-layout
transitive-bullshit
Helps with grouping, alignment, reading order, responsive structure and room for translated text, so a layout holds up when it is resized, translated or…
SkillAFreshness: A★ 4Claude Code +9 - 0.606score
better-typography
transitive-bullshit
Sets and reviews how text renders in your product, from the type scale and spacing to font features, wrapping, truncation and punctuation.
SkillAFreshness: A★ 4Claude Code +9 - 0.606score
better-colors
transitive-bullshit
Helps you build and check a color system for your project.
SkillAFreshness: A★ 4Claude Code +9 - 0.606score
better-ui
transitive-bullshit
Polishes the surfaces, icons and motion in your project with exact values for border radius, optical alignment, shadows, icon states and animation.
SkillAFreshness: A★ 4Claude Code +9 - 0.582score
create-verification-skill
transitive-bullshit
Generate a project-local verification skill that drives your app the way a user does — any language, framework, or platform.
SkillAFreshness: A★ 4Claude Code +9 - 0.580score
domain-modeling
transitive-bullshit
Build and sharpen a project's domain model.
SkillAFreshness: A★ 4Claude Code +9 - 0.580score
codebase-design
transitive-bullshit
Shared vocabulary for designing deep modules.
SkillAFreshness: A★ 4Claude Code +9 - 0.578score
resolving-merge-conflicts
transitive-bullshit
Use when you need to resolve an in-progress git merge/rebase conflict.
SkillAFreshness: A★ 4Claude Code +9 - 0.577score
testing-strategy
transitive-bullshit
Choose proportionate verification and maintain useful tests when implementing changes, fixing bugs, or reviewing test coverage.
SkillAFreshness: A★ 4Claude Code +9
Signals
- Stars
- 4
- Forks
- 1
- Open issues
- 0
- Last commit (this folder)
- Oct 11, 2026 (17 days ago)
- Last release
- Sep 6, 2026 (1 month ago)
From GitHub (fetched Oct 24, 2026).
Details
- License
- MIT
- Repository
- github.com/transitive-bullshit/skills
- First seen
- Oct 24, 2026
- Last checked
- Oct 24, 2026
- Source
- GitHubgithub-graphql
Same skill elsewhere
Copies of this SKILL.md published by others; search shows only one of them.
- 0.347score
better-accessibility
itsmichaelwest
Reviews and fixes keyboard and focus behavior, ARIA, accessible names, forms, screen-reader announcements, motion and zoom in your project against WCAG 2.2.
SkillAFreshness: A★ 1Claude Code +9 - 0.337score
better-accessibility
jorgesolerrr
Reviews and fixes keyboard and focus behavior, ARIA, accessible names, forms, screen-reader announcements, motion and zoom in your project against WCAG 2.2.
SkillAFreshness: AClaude Code +9 - 0.334score
better-accessibility
ManatoYamashita
Reviews and fixes keyboard and focus behavior, ARIA, accessible names, forms, screen-reader announcements, motion and zoom in your project against WCAG 2.2.
SkillAFreshness: AClaude Code +9
More from transitive-bullshit
- 0.606score
better-writing
transitive-bullshit
Writes and reviews your interface copy, from labels and errors to empty states and confirmations, so it matches your product's voice and tells people what to…
SkillAFreshness: A★ 4Claude Code +9 - 0.606score
better-layout
transitive-bullshit
Helps with grouping, alignment, reading order, responsive structure and room for translated text, so a layout holds up when it is resized, translated or…
SkillAFreshness: A★ 4Claude Code +9 - 0.606score
better-typography
transitive-bullshit
Sets and reviews how text renders in your product, from the type scale and spacing to font features, wrapping, truncation and punctuation.
SkillAFreshness: A★ 4Claude Code +9 - 0.606score
better-colors
transitive-bullshit
Helps you build and check a color system for your project.
SkillAFreshness: A★ 4Claude Code +9 - 0.606score
better-ui
transitive-bullshit
Polishes the surfaces, icons and motion in your project with exact values for border radius, optical alignment, shadows, icon states and animation.
SkillAFreshness: A★ 4Claude Code +9 - 0.582score
create-verification-skill
transitive-bullshit
Generate a project-local verification skill that drives your app the way a user does — any language, framework, or platform.
SkillAFreshness: A★ 4Claude Code +9
Cite this page
better-accessibility skill. Agent Mart. https://agentmart.dev/skills/transitive-bullshit-better-accessibility (last updated 2026-10-24)