---
name: tailwindcss-accessibility
description: Tailwind CSS accessibility patterns including WCAG 2.2 compliance, touch targets, focus management, and ARIA support
---
# Tailwind CSS Accessibility Patterns (WCAG 2.2 - 2025/2026)
## WCAG 2.2 Overview (Current Standard)
WCAG 2.2 was released October 2023 and is the current W3C standard. Key additions relevant to Tailwind:
- **2.5.8 Target Size (Level AA)**: 24x24 CSS pixels minimum, 44x44 recommended
- **2.4.11 Focus Not Obscured**: Focus indicators must be visible
- **2.4.13 Focus Appearance**: Enhanced focus indicator requirements
- **3.3.7 Redundant Entry**: Don't require re-entering information
- **3.2.6 Consistent Help**: Help mechanisms in consistent locations
## Focus Management
### Focus Ring Utilities
```html
Button
Only shows ring for keyboard focus
```
```css
@layer components {
.focus-ring {
@apply focus:outline-none focus-visible:ring-2 focus-visible:ring-brand-500 focus-visible:ring-offset-2;
}
.focus-ring-inset {
@apply focus:outline-none focus-visible:ring-2 focus-visible:ring-brand-500 focus-visible:ring-inset;
}
}
```
### Skip Links
```html
Skip to main content
Main content
```
### Focus Trap Pattern
```html
Modal Title
Modal content
Close
```
## Screen Reader Utilities
### Visually Hidden Content
```html
Additional context for screen readers
Skip to main
...
Close menu
Search
```
### Announcing Dynamic Content
```html
3 items added to cart
Error: Please correct the form
```
## Color Contrast
### High Contrast Patterns
```html
4.5:1 contrast ratio
May not meet WCAG AA (3:1 min for large text)
Large text - 3:1 ratio OK
Accessible Button
```
### Dark Mode Contrast
```html
High contrast text
Secondary text with adequate contrast
⚠️ May have contrast issues in dark mode
```
### Focus Indicator Contrast
```css
@theme {
/* High contrast focus ring */
--color-focus: oklch(0.55 0.25 250);
--color-focus-offset: oklch(1 0 0);
}
```
```html
High contrast focus
```
## Motion and Animation
### Reduced Motion
```html
Bouncing element (static for motion-sensitive users)
Fades in (instant for motion-sensitive)
Scales on hover (shadow only for motion-sensitive)
```
### Safe Animation Patterns
```css
@layer components {
/* Animations that respect reduced motion */
.animate-fade-in {
@apply animate-in fade-in duration-300;
@apply motion-reduce:animate-none motion-reduce:opacity-100;
}
.animate-slide-up {
@apply animate-in slide-in-from-bottom-4 duration-300;
@apply motion-reduce:animate-none motion-reduce:translate-y-0;
}
}
```
### Pause Animation on Hover
```html
Loading spinner
```
## Form Accessibility
### Accessible Form Fields
```html
```
### Error States
```html
```
### Form Validation Feedback
```css
/* Style based on aria-invalid attribute */
@custom-variant aria-invalid (&[aria-invalid="true"]);
```
```html
```
## Interactive Components
### Accessible Buttons
```html
Submit
...
Loading...
...
Toggle feature
Feature
```
### Accessible Dropdowns
```html
```
### Accessible Tabs
```html
Profile
Settings
Profile content
Settings content
```
## Touch Targets (WCAG 2.2 - Critical for 2025/2026)
### WCAG 2.2 Target Size Requirements
| Level | Requirement | Tailwind Class |
|-------|-------------|----------------|
| **AA (2.5.8)** | 24x24 CSS pixels minimum | `min-h-6 min-w-6` |
| **Recommended** | 44x44 CSS pixels | `min-h-11 min-w-11` |
| **AAA (2.5.5)** | 44x44 CSS pixels | `min-h-11 min-w-11` |
| **Optimal** | 48x48 CSS pixels | `min-h-12 min-w-12` |
Platform guidelines comparison:
- **Apple iOS**: 44x44 points minimum
- **Google Android**: 48x48 dp minimum
- **Microsoft Fluent**: 44x44 pixels minimum
### Minimum Touch Target Size
```html
...
...
Action
Primary Action
```
### Extend Touch Target Beyond Visible Element
```html
Small Link Text
...
Close menu
Card Title
Description text
View details
```
### Spacing Between Interactive Elements
WCAG 2.2 requires 24px spacing OR targets must be 24px minimum:
```html
Button 1
Button 2
Link 1
Link 2
Link 3
Cancel
Confirm
```
### Touch Target Exceptions (WCAG 2.2)
Targets can be smaller than 24x24 if:
- Inline text links within sentences
- Browser-provided controls (scrollbars)
- Size is essential to information
- A larger equivalent target exists on same page
## Text Accessibility
### Readable Text
```html
Long form content with comfortable line height
Content with optimal line length (45-75 characters)
```
### Text Resizing
```html
Scales with user's font size preferences
⚠️ Won't scale with browser zoom
Content height adjusts with text size
```
## Semantic HTML with Tailwind
### Landmark Regions
```html
Page Title
```
### Heading Hierarchy
```html
Main Title (H1)
Section (H2)
Subsection (H3)
Content...
```
## Testing Accessibility
### Browser DevTools Checklist
1. **Color contrast**: Use contrast checker
2. **Focus order**: Tab through the page
3. **Zoom**: Test at 200% zoom
4. **Reduced motion**: Enable in OS settings
### Automated Testing
```javascript
// axe-core integration
import { axe, toHaveNoViolations } from 'jest-axe';
expect.extend(toHaveNoViolations);
test('component is accessible', async () => {
const { container } = render( );
const results = await axe(container);
expect(results).toHaveNoViolations();
});
```
## Best Practices Summary (WCAG 2.2 - 2025/2026)
| Pattern | Implementation | WCAG Level |
|---------|---------------|------------|
| Focus visible | `focus-visible:ring-2 focus-visible:ring-offset-2` | 2.4.7 (AA) |
| Screen reader only | `sr-only` | 1.3.1 (A) |
| Skip links | `sr-only focus:not-sr-only focus:absolute` | 2.4.1 (A) |
| Reduced motion | `motion-reduce:animate-none motion-reduce:transition-none` | 2.3.3 (AAA) |
| Touch targets (min) | `min-h-6 min-w-6` (24px) | 2.5.8 (AA) |
| Touch targets (rec) | `min-h-11 min-w-11` (44px) | 2.5.5 (AAA) |
| Touch spacing | `gap-3` (12px minimum between targets) | 2.5.8 (AA) |
| Text contrast | 4.5:1 for normal, 3:1 for large text | 1.4.3 (AA) |
| Form errors | `aria-invalid="true"` + `role="alert"` | 3.3.1 (A) |
| Focus not obscured | Avoid `z-index` covering focused elements | 2.4.11 (AA) |
### Quick Reference: Touch-Friendly Component
```html
Button Text
```