frontend-a11y
Helps your agent make web interfaces accessible to everyone. It ensures websites and apps work well with screen readers and keyboard navigation.
What it does
Helps make websites and apps easier for everyone to use, especially people with disabilities. It ensures buttons, forms, and other elements work correctly with screen readers and keyboard navigation.
When to use it
- ✓When creating website forms.
- ✓When adding interactive buttons or menus.
- ✓When receiving accessibility warnings in your code.
Example of what to ask your AI
“How do I make my login form accessible for visually impaired users?”
Want more? Open the sections below.
How to use
The easiest way: copy the message below and paste it into Claude, ChatGPT, Cursor or any AI. It reads the skill and follows the instructions.
Skill link
Ready-to-paste message
How it works
The agent inserts specific code snippets (like 'htmlFor', 'aria-label') that help screen readers understand and interact with page elements. It also suggests using the correct HTML tags for each function.
Installation
Easiest way: copy the skill link and paste it into Claude, ChatGPT or Cursor asking it to follow the instructions.
In the terminal (Claude Code, Codex, Cursor), in your project folder:
npx skills add affaan-m/ECC --skill frontend-a11yOr download just the file:
curl -L https://raw.githubusercontent.com/affaan-m/ECC/main/pi/core/skills/frontend-a11y/SKILL.md -o SKILL.mdTechnical content (original SKILL.md)
Original text by the author, straight from GitHub.
Frontend Accessibility Patterns
Practical accessibility patterns for React and Next.js. Covers the issues most commonly flagged in code review: missing form labels, incorrect ARIA usage, non-semantic interactive elements, and broken keyboard navigation.
When to Activate
- Building or reviewing form components (
<input>,<select>,<textarea>) - Creating interactive elements (modals, dropdowns, tooltips, tabs)
- Using
<div>or<span>withonClick - Adding
aria-*attributes to any element - Implementing keyboard navigation or focus management
- Receiving accessibility feedback from code review tools (CodeRabbit, ESLint a11y)
- Building components that must support screen readers
Form Accessibility
Missing htmlFor / id pairing and disconnected error messages are the most common issues flagged in code review.
Label Connection
// BAD: label has no connection to input — screen readers cannot associate them
<label>Email</label>
<input type="email" />
// GOOD: htmlFor matches input id
<label htmlFor="email">Email</label>
<input id="email" type="email" />
Required Fields
// BAD: visual-only asterisk conveys nothing to screen readers
<label htmlFor="email">Email *</label>
<input id="email" type="email" />
// GOOD: required enables native browser validation; aria-required signals it to screen readers
<label htmlFor="email">
Email <span aria-hidden="true">*</span>
</label>
<input id="email" type="email" required aria-required="true" />
Error Messages
// BAD: error text exists visually but is not linked to the input
<input id="email" type="email" />
<span className="error">Invalid email address</span>
// GOOD: aria-describedby connects input to its error message
// aria-invalid signals the invalid state to screen readers
<input
id="email"
type="email"
aria-describedby="email-error"
aria-invalid={!!error}
/>
{error && (
<span id="email-error" role="alert">
{error}
</span>
)}
Complete Accessible Form
interface LoginFormProps {
onSubmit: (email: string, password: string) => void;
}
export function LoginForm({ onSubmit }: LoginFormProps) {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [errors, setErrors] = useState<{ email?: string; password?: string }>({});
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
const newErrors: typeof errors = {};
if (!email) newErrors.email = 'Email is required';
if (!password) newErrors.password = 'Password is required';
if (Object.keys(newErrors).length) {
setErrors(newErrors);
return;
}
onSubmit(email, password);
};
return (
<form onSubmit={handleSubmit} noValidate>
<div>
<label htmlFor="email">
Email <span aria-hidden="true">*</span>
</label>
<input
id="email"
type="email"
value={email}
onChange={e => setEmail(e.target.value)}
aria-required="true"
aria-describedby={errors.email ? 'email-error' : undefined}
aria-invalid={!!errors.email}
autoComplete="email"
/>
{errors.email && (
<span id="email-error" role="alert">
{errors.email}
</span>
)}
</div>
<div>
<label htmlFor="password">
Password <span aria-hidden="true">*</span>
</label>
<input
id="password"
type="password"
value={password}
onChange={e => setPassword(e.target.value)}
aria-required="true"
aria-describedby={errors.password ? 'password-error' : undefined}
aria-invalid={!!errors.password}
autoComplete="current-password"
/>
{errors.password && (
<span id="password-error" role="alert">
{errors.password}
</span>
)}
</div>
<button type="submit">Log in</button>
</form>
);
}
Semantic HTML
Use the element that matches the intent. Screen readers and keyboard users depend on native semantics.
// BAD: div has no role, no keyboard support, no accessible name
<div onClick={handleClick}>Submit</div>
// GOOD: button is focusable, activates on Enter/Space, announces as "button"
<button type="button" onClick={handleClick}>Submit</button>
// BAD: non-semantic navigation
<div onClick={() => navigate('/home')}>Home</div>
…
FAQ
What are 'screen readers'?
These are programs that read screen content aloud, helping people with visual impairments use computers and phones.
Why use 'aria-label' or 'htmlFor'?
These codes link labels to form fields or buttons, ensuring screen readers announce the correct purpose of the element.
When should I use a 'div' with 'onClick'?
Generally, you shouldn't. It's better to use the <button> tag, which already has built-in accessibility features like keyboard clickability.
Details
Original description by the author
Accessibility patterns for React and Next.js — semantic HTML, ARIA attributes, form labeling, keyboard navigation, focus management, and screen reader support. Use when building or reviewing forms, modals, dropdowns, tooltips, or tabs, fixing a11y lint or code-review findings, or wiring up keyboard navigation and focus management.
repo: affaan-m/ECC
Popularity
- GitHub stars
- 280k
- Ranking position
- #57
- License
- MIT
- Updated
- 10/15/2026
Comments
- …
More skills from this repository
accessibility
Helps your agent create interfaces that everyone can use. Ensures websites and apps work well for people with disabilities, like those who are blind or have reduced mobility.
affaan-m/ECC
agent-architecture-audit
Makes your agent check if everything is working correctly. It finds and fixes problems in AI systems, ensuring they perform as expected.
affaan-m/ECC
agent-eval
Helps your agent compare different AI coding tools. It measures which one is faster, cheaper, and more reliable for specific tasks.
affaan-m/ECC
agent-harness-construction
Makes your agent better understand how to perform tasks. It optimizes the tools and instructions the agent uses to increase its chances of success.
affaan-m/ECC
Similar skills
web-artifacts-builder
Helps your agent build complex HTML artifacts using modern technologies. Ideal for interfaces with state management and advanced components.
anthropics/skills
frontend-ui-engineering
Helps your agent build beautiful and easy-to-use user interfaces. Makes the output look professional and work well on different devices.
addyosmani/agent-skills
export-nextjs-handoff
Makes your agent turn designs into Next.js code. It creates components, styles, and notes to help the developer.
nexu-io/open-design