--- 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
...
...
...
// Good: semantic elements
...
...
``` ### 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 // Visually hidden section headings

{t("Search results")}

``` #### aria-live-regions - @rules/aria-live-regions.md Announce dynamic content changes to screen readers. ```tsx // Error messages - announced immediately { error && (

{error}

); } // Status updates - announced politely
{t("{{count}} results found", { count })}
; ``` ### 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
Click me
// Good: button has Enter/Space support // Good: react-aria Button handles everything import { Button } from "react-aria-components"; ``` #### focus-management - @rules/focus-management.md Show visible focus indicators and trap focus in modals. ```tsx // Always use focus-visible for focus styles ; // react-aria Modal handles focus trapping automatically import { Modal, Dialog } from "react-aria-components"; {/* Focus automatically trapped here */} ; ``` ### 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
Bouncing content
; // JS approach function AnimatedCounter({ value }) { let prefersReducedMotion = usePrefersReducedMotion(); if (prefersReducedMotion) return {value}; return ; } ``` #### touch-targets - @rules/touch-targets.md Ensure 44x44px minimum touch targets. ```tsx // Icon buttons need explicit sizing // Links need padding for tappable area {label} ``` ## 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