frontend-accessibility-best-practices — Claude Code skill: React a11y
A skill with 7 accessibility rules for React: semantic markup, screen readers, keyboard support, user preferences. Useful when you build forms and interactive elements.
npx skills add sergiodxa/agent-skills --skill frontend-accessibility-best-practices -a claude-codeWhat frontend-accessibility-best-practices does
The skill is split into 4 categories and 7 rules. Semantic landmarks and keyboard navigation are marked HIGH, screen reader support and user preferences MEDIUM. Each rule lives in its own file under @rules/, and the agent pulls them in when you ask for a component, a form, or an accessibility review.
Inside are TSX examples: swapping a div with a class for <header> and <nav aria-label>, labelling an icon-only button with sr-only, announcing an error via role="alert" and a status via role="status" aria-live="polite". Focus rings, focus trapping in modals, prefers-reduced-motion and the 44x44px touch target minimum each get their own rule.
The examples lean on react-aria-components and a usePrefersReducedMotion hook, plus the files app/components/heading.tsx, app/components/field/field.tsx and app/hooks/use-prefers-reduced-motion.ts. If your project doesn't use react-aria, some snippets need rewriting against your own components — a good reason to check what already handles focus and modals for you.
What it helps with
- structure a page with semantic elements instead of classed divs
- give an icon-only button a label screen readers can read
- announce a form error at once and a result count politely
- trap focus inside a modal and restore it on close
- turn off animation for users who asked for less motion
Example prompts for the agent
- Build a React login form and check it against the skill's a11y rules
- Review this component for accessibility: focus, keyboard, screen readers
- Make a modal with focus trapping and labelled icons
How to install frontend-accessibility-best-practices
1Skills CLI (Vercel)
npx skills add sergiodxa/agent-skills --skill frontend-accessibility-best-practices -a claude-code2Manually: put the files in place
~/.claude/skills/frontend-accessibility-best-practices/SKILL.mdCopy the whole skill folder; for one project use .claude/skills/frontend-accessibility-best-practices/
1Skills CLI (Vercel)
npx skills add sergiodxa/agent-skills --skill frontend-accessibility-best-practices -a codex2Manually: put the files in place
.agents/skills/frontend-accessibility-best-practices/SKILL.mdFor all projects use ~/.agents/skills/
1Skills CLI (Vercel)
npx skills add sergiodxa/agent-skills --skill frontend-accessibility-best-practices -a cursor2Manually: put the files in place
.cursor/skills/frontend-accessibility-best-practices/SKILL.mdCursor also reads .agents/skills/ and .claude/skills/
1GitHub CLI
gh skill install sergiodxa/agent-skills frontend-accessibility-best-practices2Manually: put the files in place
.github/skills/frontend-accessibility-best-practices/SKILL.md1Skills CLI (Vercel)
npx skills add sergiodxa/agent-skills --skill frontend-accessibility-best-practices -a gemini-cli2Platform CLI
gemini skills install https://github.com/sergiodxa/agent-skills --path skills/frontend-accessibility-best-practicesManually: put the files in place
.devin/skills/frontend-accessibility-best-practices/SKILL.mdThe legacy .windsurf/skills/ path still works
Skills CLI (Vercel)
npx skills add sergiodxa/agent-skills --skill frontend-accessibility-best-practices -a opencodeClaude.ai
Zip the folder and upload it in Settings → Capabilities → Skills
Step by step, with commands for each platform: How to install skills in Claude Code: five ways
Questions about frontend-accessibility-best-practices
How do I install frontend-accessibility-best-practices in Claude?
Run npx skills add sergiodxa/agent-skills --skill frontend-accessibility-best-practices -a claude-code. The skill file then lands at ~/.claude/skills/frontend-accessibility-best-practices/SKILL.md.
What does frontend-accessibility-best-practices do?
It hands the agent a set of React accessibility rules: semantic structure, screen reader support, keyboard navigation and user preferences. The agent applies them while writing components and during code review.
Do I need react-aria for this skill?
No, but the focus trapping and button examples use react-aria-components. Without that library you'll adapt those snippets to your own components.
Source text
SKILL.md · MIT
---
name: frontend-accessibility-best-practices
description: Accessibility (a11y) best practices for React components. Use when creating UI components, forms, interactive elements, or reviewing code for accessibility compliance.
---
# Accessibility Best Practices
Accessibility patterns for building inclusive React applications following WCAG standards. Contains 7 rules across 4 categories focused on semantic HTML, screen reader support, keyboard navigation, and user preferences.
## When to Apply
Reference these guidelines when:
- Creating new UI components
- Building forms and interactive elements
- Adding dynamic content or notifications
- Implementing navigation patterns
- Reviewing code for accessibility
## Rules Summary
### Semantic HTML & Structure (HIGH)
#### semantic-html-landmarks - @rules/semantic-html-landmarks.md
Use semantic HTML elements for page structure.
```tsx
// Bad: divs with class names
<div className="header">...</div>
<div className="nav">...</div>
<div className="content">...</div>
// Good: semantic elements
<header>...</header>
<nav aria-label={t("Primary")}>...</nav>
<main>...</main>
<footer>...</footer>
```
### Screen Readers (MEDIUM)
#### screen-reader-sr-only - @rules/screen-reader-sr-only.md
Use sr-only class for visually hidden text.
```tsx
// Icon-only buttons need accessible labels
<Button variant="icon" onPress={onClose}>
<XMarkIcon aria-hidden="true" />
<span className="sr-only">{t("Close")}</span>
</Button>
// Visually hidden section headings
<section>
<h2 className="sr-only">{t("Search results")}</h2>
<SearchResultsList />
</section>
```
#### aria-live-regions - @rules/aria-live-regions.md
Announce dynamic content changes to screen readers.
```tsx
// Error messages - announced immediately
{
error && (
<p role="alert" className="text-failure-600">
{error}
</p>
);
}
// Status updates - announced politely
<div role="status" aria-live="polite">
{t("{{count}} results found", { count })}
</div>;
```
### Keyboard & Focus (HIGH)
#### keyboard-navigation - @rules/keyboard-navigation.md
Use semantic elements for built-in keyboard support.
```tsx
// Bad: div with onClick not keyboard accessible
<div onClick={handleClick}>Click me</div>
// Good: button has Enter/Space support
<button onClick={handleClick}>Click me</button>
// Good: react-aria Button handles everything
import { Button } from "react-aria-components";
<Button onPress={handlePress}>Click me</Button>
```
#### focus-management - @rules/focus-management.md
Show visible focus indicators and trap focus in modals.
```tsx
// Always use focus-visible for focus styles
<button className="focus-visible:ring-2 focus-visible:ring-teal-600">
Click me
</button>;
// react-aria Modal handles focus trapping automatically
import { Modal, Dialog } from "react-aria-components";
<Modal isOpen={isOpen}>
<Dialog>{/* Focus automatically trapped here */}</Dialog>
</Modal>;
```
### User Preferences (MEDIUM)
#### reduced-motion - @rules/reduced-motion.md
Respect prefers-reduced-motion setting.
```tsx
import { usePrefersReducedMotion } from "~/hooks/use-prefers-reduced-motion";
// CSS approach
<div className="animate-bounce motion-reduce:animate-none">
Bouncing content
</div>;
// JS approach
function AnimatedCounter({ value }) {
let prefersReducedMotion = usePrefersReducedMotion();
if (prefersReducedMotion) return <span>{value}</span>;
return <CountUp target={value} />;
}
```
#### touch-targets - @rules/touch-targets.md
Ensure 44x44px minimum touch targets.
```tsx
// Icon buttons need explicit sizing
<Button variant="icon" className="h-11 w-11">
<XMarkIcon className="h-5 w-5" />
<span className="sr-only">{t("Close")}</span>
</Button>
// Links need padding for tappable area
<Link to={href} className="block py-3 px-4">
{label}
</Link>
```
## Key Files
- `app/components/heading.tsx` - Region, Heading, Main components
- `app/hooks/use-prefers-reduced-motion.ts` - Reduced motion hook
- `app/components/field/field.tsx` - Accessible form field component
© sergiodxa · MIT · sergiodxa/agent-skills