aria-patterns
Provides ARIA roles, states, and properties for interactive components. Use when building custom widgets, fixing screen reader issues, or implementing modals, tabs, accordions, menus, or dialogs accessibly.
Best use case
aria-patterns is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
Provides ARIA roles, states, and properties for interactive components. Use when building custom widgets, fixing screen reader issues, or implementing modals, tabs, accordions, menus, or dialogs accessibly.
Teams using aria-patterns should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/aria-patterns/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How aria-patterns Compares
| Feature / Agent | aria-patterns | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
Provides ARIA roles, states, and properties for interactive components. Use when building custom widgets, fixing screen reader issues, or implementing modals, tabs, accordions, menus, or dialogs accessibly.
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
# ARIA Patterns Guide
## Overview
Implement accessible interactive components using correct ARIA roles, states, and properties. Provides copy-paste patterns for common widgets that work with screen readers and keyboard navigation.
## When to Use
- Building custom interactive components
- Making dynamic content accessible
- Fixing screen reader issues
- Adding keyboard support to custom widgets
## Quick Reference: First Rules of ARIA
1. **Don't use ARIA if native HTML works** - `<button>` over `<div role="button">`
2. **Don't change native semantics** - Don't put `role="button"` on a heading
3. **All interactive ARIA elements must be keyboard accessible**
4. **Don't use `role="presentation"` or `aria-hidden="true"` on focusable elements**
5. **All interactive elements must have accessible names**
## The Process
1. **Identify component type**: What widget pattern matches?
2. **Check native HTML first**: Can a semantic element do this?
3. **Apply ARIA pattern**: Roles, states, properties
4. **Add keyboard support**: Expected keys for the pattern
5. **Test with screen reader**: Verify announcements
## Component Patterns
### Button
**Native (preferred):**
```html
<button type="button">Click me</button>
```
**Custom (when necessary):**
```html
<div
role="button"
tabindex="0"
aria-pressed="false"
onkeydown="handleKeyDown(event)"
>
Toggle
</div>
<script>
function handleKeyDown(e) {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
e.target.click();
}
}
</script>
```
### Toggle Button
```html
<button
type="button"
aria-pressed="false"
onclick="this.setAttribute('aria-pressed', this.getAttribute('aria-pressed') === 'true' ? 'false' : 'true')"
>
<span class="sr-only">Enable</span> Dark Mode
</button>
```
---
### Modal Dialog
```html
<div
role="dialog"
aria-modal="true"
aria-labelledby="modal-title"
aria-describedby="modal-desc"
>
<h2 id="modal-title">Confirm Action</h2>
<p id="modal-desc">Are you sure you want to proceed?</p>
<button type="button">Cancel</button>
<button type="button">Confirm</button>
</div>
```
**Required behavior:**
- Focus moves to dialog on open
- Focus trapped within dialog
- Escape key closes dialog
- Focus returns to trigger on close
```js
// Focus trap example
function trapFocus(dialog) {
const focusable = dialog.querySelectorAll(
'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
);
const first = focusable[0];
const last = focusable[focusable.length - 1];
dialog.addEventListener('keydown', (e) => {
if (e.key === 'Tab') {
if (e.shiftKey && document.activeElement === first) {
e.preventDefault();
last.focus();
} else if (!e.shiftKey && document.activeElement === last) {
e.preventDefault();
first.focus();
}
}
});
}
```
---
### Dropdown Menu
```html
<div class="dropdown">
<button
type="button"
aria-haspopup="menu"
aria-expanded="false"
aria-controls="dropdown-menu"
id="dropdown-trigger"
>
Options
</button>
<ul
role="menu"
id="dropdown-menu"
aria-labelledby="dropdown-trigger"
hidden
>
<li role="none">
<button role="menuitem" tabindex="-1">Edit</button>
</li>
<li role="none">
<button role="menuitem" tabindex="-1">Duplicate</button>
</li>
<li role="none">
<button role="menuitem" tabindex="-1">Delete</button>
</li>
</ul>
</div>
```
**Keyboard:**
- Enter/Space: Open menu, activate item
- Arrow Down: Next item (or first if closed)
- Arrow Up: Previous item
- Escape: Close menu
- Home: First item
- End: Last item
---
### Tabs
```html
<div class="tabs">
<div role="tablist" aria-label="Account settings">
<button
role="tab"
aria-selected="true"
aria-controls="panel-1"
id="tab-1"
tabindex="0"
>
Profile
</button>
<button
role="tab"
aria-selected="false"
aria-controls="panel-2"
id="tab-2"
tabindex="-1"
>
Security
</button>
<button
role="tab"
aria-selected="false"
aria-controls="panel-3"
id="tab-3"
tabindex="-1"
>
Billing
</button>
</div>
<div role="tabpanel" id="panel-1" aria-labelledby="tab-1" tabindex="0">
Profile content...
</div>
<div role="tabpanel" id="panel-2" aria-labelledby="tab-2" tabindex="0" hidden>
Security content...
</div>
<div role="tabpanel" id="panel-3" aria-labelledby="tab-3" tabindex="0" hidden>
Billing content...
</div>
</div>
```
**Keyboard:**
- Arrow Left/Right: Move between tabs
- Home: First tab
- End: Last tab
- Tab: Move into panel content
---
### Accordion
```html
<div class="accordion">
<h3>
<button
type="button"
aria-expanded="true"
aria-controls="section-1"
id="accordion-header-1"
>
Section 1
</button>
</h3>
<div
role="region"
id="section-1"
aria-labelledby="accordion-header-1"
>
Section 1 content...
</div>
<h3>
<button
type="button"
aria-expanded="false"
aria-controls="section-2"
id="accordion-header-2"
>
Section 2
</button>
</h3>
<div
role="region"
id="section-2"
aria-labelledby="accordion-header-2"
hidden
>
Section 2 content...
</div>
</div>
```
---
### Tooltip
```html
<button
type="button"
aria-describedby="tooltip-1"
>
Help
</button>
<div
role="tooltip"
id="tooltip-1"
hidden
>
Click here for more information
</div>
```
**Note:** For interactive content, use a disclosure or dialog instead.
---
### Alert / Status Messages
```html
<!-- Alert (important, interruptive) -->
<div role="alert">
Error: Please enter a valid email address.
</div>
<!-- Status (polite update) -->
<div role="status" aria-live="polite">
3 items in cart
</div>
<!-- Live region (for dynamic content) -->
<div aria-live="polite" aria-atomic="true">
<!-- Content updates announced to screen readers -->
</div>
```
---
### Combobox (Autocomplete)
```html
<div class="combobox">
<label for="search-input">Search</label>
<input
type="text"
id="search-input"
role="combobox"
aria-autocomplete="list"
aria-expanded="false"
aria-controls="search-listbox"
aria-activedescendant=""
>
<ul
role="listbox"
id="search-listbox"
hidden
>
<li role="option" id="option-1">Option 1</li>
<li role="option" id="option-2">Option 2</li>
<li role="option" id="option-3" aria-selected="true">Option 3</li>
</ul>
</div>
```
**Update `aria-activedescendant` to the ID of the highlighted option.**
---
### Progress / Loading
```html
<!-- Determinate progress -->
<div
role="progressbar"
aria-valuenow="75"
aria-valuemin="0"
aria-valuemax="100"
aria-label="Upload progress"
>
75%
</div>
<!-- Indeterminate loading -->
<div
role="status"
aria-label="Loading"
>
<span class="spinner" aria-hidden="true"></span>
<span class="sr-only">Loading...</span>
</div>
```
---
## Common ARIA Attributes
| Attribute | Purpose | Example |
|-----------|---------|---------|
| `aria-label` | Accessible name | `aria-label="Close"` |
| `aria-labelledby` | Name from element | `aria-labelledby="heading-1"` |
| `aria-describedby` | Description | `aria-describedby="hint-1"` |
| `aria-expanded` | Open/closed state | `aria-expanded="true"` |
| `aria-controls` | Controlled element | `aria-controls="menu-1"` |
| `aria-hidden` | Hide from AT | `aria-hidden="true"` |
| `aria-live` | Announce updates | `aria-live="polite"` |
| `aria-pressed` | Toggle state | `aria-pressed="false"` |
| `aria-selected` | Selection state | `aria-selected="true"` |
| `aria-current` | Current item | `aria-current="page"` |
## Screen Reader Only Text
```css
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border-width: 0;
}
```
## Testing
1. **Keyboard only**: Tab through, use arrows, Enter, Escape
2. **Screen reader**: Test with VoiceOver (Mac), NVDA (Windows), or JAWS
3. **Check announcements**: Are labels, states, and changes announced?
4. **axe DevTools**: Run automated accessibility auditRelated Skills
analyze-patterns
Use this skill when you need to analyze code for design patterns, anti-patterns, naming conventions, and code duplication. This skill excels at identifying architectural patterns, detecting code smells, and ensuring consistency across the codebase.
acc-stability-patterns-knowledge
Stability Patterns knowledge base. Provides patterns, antipatterns, and PHP-specific guidelines for Circuit Breaker, Retry, Rate Limiter, Bulkhead, and resilience audits.
a2a-patterns
Agent-to-Agent (A2A) protocol implementation patterns for Google ADK - exposing agents via A2A, consuming external agents, multi-agent communication, and protocol configuration. Use when building multi-agent systems, implementing A2A protocol, exposing agents as services, consuming remote agents, configuring agent cards, or when user mentions A2A, agent-to-agent, multi-agent collaboration, remote agents, or agent orchestration.
wcag-audit-patterns
Conduct WCAG 2.2 accessibility audits with automated testing, manual verification, and remediation guidance. Use when auditing websites for accessibility, fixing WCAG violations, or implementing ac...
testing-patterns
Testing patterns using bun:test with in-memory SQLite. Use when writing unit tests, integration tests, or router tests.
midnight-dapp:testing-patterns
Use when writing unit tests for Midnight contract interaction code, integration testing without ZK proofs, E2E testing with Playwright or Cypress, or setting up CI/CD pipelines for Midnight DApps.
e2e-testing-patterns
Master end-to-end testing with Playwright and Cypress to build reliable test suites that catch bugs, improve confidence, and enable fast deployment. Use when implementing E2E tests, debugging flaky tests, or establishing testing standards.
code-review-patterns
Internal skill. Use cc10x-router for all development tasks.
auth-implementation-patterns
Master authentication and authorization patterns including JWT, OAuth2, session management, and RBAC to build secure, scalable access control systems. Use when implementing auth systems, securing A...
responsive-design-patterns
Mobile-first responsive design patterns with breakpoints, fluid layouts, and adaptive components
react-fluent-ui-patterns
Skill for React TypeScript frontend development with Fluent UI Copilot components. Use when creating UI components, handling SSE streams, working with chat interfaces, or implementing theme support.
aria-expert
Expert knowledge of WAI-ARIA (Accessible Rich Internet Applications). Use when users ask about ARIA roles, states, properties, accessible name computation, ARIA attributes (aria-label, aria-labelledby, aria-describedby, etc.), widget roles, landmark roles, live regions, ARIA best practices, or how to implement accessible interactive components. Also use for questions about ARIA specifications, API mappings (core-aam, html-aam), digital publishing ARIA (dpub-aria), graphics ARIA, or any ARIA implementation questions.