rule-accessibility
Enforces WCAG 2.1 AA and Section 508 accessibility compliance for front-end code.
Install
mkdir -p .claude/skills/rule-accessibility && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/14466" && unzip -o skill.zip -d .claude/skills/rule-accessibility && rm skill.zipInstalls to .claude/skills/rule-accessibility
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
MANDATORY when editing files matching ["frontend/src/**/*.tsx", "frontend/src/**/*.ts"]. Accessibility requirements for all frontend code. WCAG 2.1 AA and Section 508 compliance is legally mandated for this federal project.Key capabilities
- →Scan component test suites for accessibility violations
- →Ensure interactive elements have ARIA labels or accessible names
- →Maintain logical tab order for keyboard navigation
- →Manage focus for modals, dialogs, and drawers
- →Enforce logical heading hierarchy with one H1 per page
- →Associate form inputs with label elements
How it works
This skill enforces WCAG 2.1 AA and Section 508 compliance by requiring specific coding patterns and Jest-axe scans for frontend components.
Inputs & outputs
When to use rule-accessibility
- →Validate component accessibility
- →Check ARIA labels
- →Run accessibility tests
About this skill
Accessibility Rules (WCAG 2.1 AA / Section 508)
This is a federal government project. Section 508 compliance and WCAG 2.1 AA conformance are legal requirements, not optional best practices. Accessibility violations are treated as bugs, not suggestions.
Jest-axe Testing (Required)
EVERY component test suite MUST include a jest-axe accessibility scan. MUST use the toHaveNoViolations() matcher. NEVER ship a component without an axe scan in its test file.
Example from codebase:
// From frontend/tests/components/manageUsers/InviteLegacyUsersButton.test.tsx
import { axe } from "jest-axe";
it("should not have accessibility violations", async () => {
const { container } = render(
<InviteLegacyUsersButton organizationId="org-123" />,
);
const results = await axe(container);
expect(results).toHaveNoViolations();
});
ARIA Labels and Roles
EVERY interactive element MUST have a proper ARIA label or accessible name. Icon-only buttons MUST have aria-label describing the action. NEVER rely on visual appearance alone to convey meaning.
Example from codebase:
// Correct: icon-only button with aria-label
<button aria-label="Close modal" onClick={onClose}>
<Icon name="close" />
</button>
// Correct: form input with associated label
<label htmlFor="search-input">Search grants</label>
<input id="search-input" type="text" />
Keyboard Navigation
ALWAYS maintain logical tab order. ALWAYS ensure all interactive elements are reachable via keyboard. NEVER use tabIndex values greater than 0 (disrupts natural tab order). ALWAYS use tabIndex={0} for custom interactive elements and tabIndex={-1} for programmatically focusable non-interactive elements.
Focus Management
ALWAYS use focus-trap-react for modals, dialogs, and drawers. ALWAYS return focus to the trigger element when a modal/dialog closes. NEVER trap focus in non-modal UI elements.
Example from codebase:
// From frontend/src/components/ modal pattern
import FocusTrap from "focus-trap-react";
<FocusTrap active={isOpen}>
<div role="dialog" aria-modal="true" aria-labelledby="modal-title">
<h2 id="modal-title">Confirm Action</h2>
{/* Modal content */}
<button onClick={onClose}>Close</button>
</div>
</FocusTrap>
Heading Hierarchy
ALWAYS maintain logical heading hierarchy (h1 > h2 > h3). NEVER skip heading levels. EVERY page MUST have exactly one <h1>. NEVER use headings for visual styling — use CSS classes instead.
Form Accessibility
EVERY form input MUST be associated with a <label> element (via htmlFor/id or wrapping). ALWAYS use aria-describedby for help text and error messages. ALWAYS use aria-invalid="true" for fields with validation errors. NEVER use placeholder text as a substitute for labels.
Example from codebase:
<label htmlFor="email-input">Email address</label>
<input
id="email-input"
type="email"
aria-describedby="email-help email-error"
aria-invalid={hasError}
/>
<span id="email-help">We will never share your email.</span>
{hasError && <span id="email-error" role="alert">Please enter a valid email.</span>}
Dynamic Content and Live Regions
ALWAYS use aria-live regions for dynamic content updates (loading states, error messages, notifications). ALWAYS use role="alert" for urgent error messages. ALWAYS use role="status" for non-urgent status updates. NEVER update DOM content without notifying assistive technology.
Example from codebase:
// Loading state announced to screen readers
<div aria-live="polite" aria-busy={isLoading}>
{isLoading ? "Loading results..." : `${count} results found`}
</div>
// Error announced immediately
<div role="alert">
{errorMessage}
</div>
Color and Visual Design
NEVER convey information solely through color. ALWAYS provide text or icons alongside color indicators. ALWAYS ensure sufficient color contrast (4.5:1 for normal text, 3:1 for large text per WCAG AA). ALWAYS use USWDS design tokens for colors — they meet contrast requirements by default.
Images and Icons
ALWAYS provide meaningful alt text for informational images. ALWAYS use aria-hidden="true" or alt="" for decorative images and icons. NEVER leave alt attributes empty on informational images.
USWDS Component Usage
ALWAYS prefer USWDS components from @trussworks/react-uswds for standard UI elements — they include built-in accessibility. NEVER reimplement functionality that USWDS provides with accessible defaults. ALWAYS verify that custom components meet or exceed USWDS accessibility standards.
Pa11y-CI Integration
Be aware that pa11y-ci runs in CI on every PR with two configurations:
- Desktop: Standard viewport with axe runner
- Mobile: 390x844 viewport (iPhone 14 equivalent)
Both wait for
#main-contentvisibility before scanning. ALWAYS ensure pages render#main-contentas a landmark.
Tables
ALWAYS use semantic <table>, <thead>, <tbody>, <th>, <td> elements for tabular data. ALWAYS use scope="col" or scope="row" on <th> elements. NEVER use tables for layout purposes. ALWAYS provide a <caption> or aria-label for data tables.
Skip Navigation
ALWAYS ensure a "Skip to main content" link exists as the first focusable element on the page. This is handled at the layout level — NEVER remove it.
Context Enrichment
When generating frontend code that affects accessibility, enrich your context:
- Call
get_architecture_section("frontend")from thesimpler-grants-contextMCP server to understand frontend architecture - Call
get_rule_detail("frontend-components")for component structure patterns - Call
get_rule_detail("frontend-tests")for jest-axe test patterns - Call
get_rule_detail("frontend-app-pages")for page-level accessibility patterns - Consult Compound Knowledge for indexed documentation on accessibility patterns
Related Rules
When working on accessibility, also consult these related rules:
frontend-components.mdc— component structure, USWDS usagefrontend-tests.mdc— jest-axe testing requirementsfrontend-e2e-tests.mdc— E2E accessibility testingfrontend-app-pages.mdc— page-level metadata and structurefrontend-i18n.mdc— translated strings for accessible labelscross-domain.mdc— cross-cutting conventions
Specialist Validation
When generating or significantly modifying frontend code:
For simple changes (< 20 lines, adding aria-label, fixing alt text): No specialist invocation needed — the directives in this rule file are sufficient.
For moderate changes (new interactive component, new form, new modal):
Invoke accessibility-auditor to validate WCAG 2.1 AA compliance.
For complex changes (new page, new layout, new navigation pattern): Invoke the following specialists (run in parallel where possible):
accessibility-auditor— deep WCAG 2.1 AA / Section 508 compliance reviewcodebase-conventions-reviewer— validate against project conventionskieran-typescript-reviewer— TypeScript-specific quality review
When not to use it
- →When working on backend code
- →When accessibility is not a legal requirement
- →When the project is not a federal government project
Limitations
- →This skill applies only to frontend code matching "frontend/src/**/*.tsx" or "frontend/src/**/*.ts" paths.
- →This skill does not cover accessibility aspects outside of the specified frontend files.
- →This skill does not provide guidance for non-federal projects where Section 508 is not mandated.
How it compares
This workflow integrates accessibility checks directly into the development process and testing, unlike manual audits after development.
Compared to similar skills
rule-accessibility side by side with the closest alternatives in the catalog.
| Skill | Installs | Updated | Safety | Difficulty |
|---|---|---|---|---|
| rule-accessibility (this skill) | 0 | 4mo | No flags | Intermediate |
| ui-ux-expert-skill | 91 | 9mo | Review | Advanced |
| ui-testing | 4 | 4mo | Review | Beginner |
| verify-bulk-action-bar | 0 | 3mo | Review | Intermediate |
Try saying
Example prompts that trigger this skill in your AI assistant.
You might also like
ui-ux-expert-skill
fercracix33
Technical workflow for implementing accessible React user interfaces with shadcn/ui, Tailwind CSS, and TanStack Query. Includes 6-phase process with mandatory Style Guide compliance, Context7 best practices consultation, Chrome DevTools validation, and WCAG 2.1 AA accessibility standards. Use after Test Agent, Implementer, and Supabase agents complete their work.
ui-testing
alinaqi
Visual testing - catch invisible buttons, broken layouts, contrast
verify-bulk-action-bar
junnv93
BulkActionBar 패턴 SSOT 검증 — count chip aria-live, role=toolbar, Esc clear, indeterminate Radix, focus management, IME guard. 일괄 작업 UI 변경 시 트리거. canonical = components/common/BulkActionBar.tsx (도메인 무관 generic), components/approvals/BulkActionBar.tsx는 approvals 특화 wrapper.
accessibility-compliance
wshobson
Implement WCAG 2.2 compliant interfaces with mobile accessibility, inclusive design patterns, and assistive technology support. Use when auditing accessibility, implementing ARIA patterns, building for screen readers, or ensuring inclusive user experiences.
radix-ui-design-system
sickn33
Build accessible design systems with Radix UI primitives. Headless component customization, theming strategies, and compound component patterns for production-grade UI libraries.
frontend-developer
sickn33
Build React components, implement responsive layouts, and handle client-side state management. Masters React 19, Next.js 15, and modern frontend architecture. Optimizes performance and ensures accessibility. Use PROACTIVELY when creating UI components or fixing frontend issues.