# WCAG 2.2 Guidelines Reference
## Overview
The Web Content Accessibility Guidelines (WCAG) 2.2 provide recommendations for making web content more accessible. They are organized into four principles (POUR): Perceivable, Operable, Understandable, and Robust.
## Conformance Levels
- **Level A**: Minimum accessibility (must satisfy)
- **Level AA**: Standard accessibility (should satisfy)
- **Level AAA**: Enhanced accessibility (may satisfy)
Most organizations target Level AA compliance.
## Principle 1: Perceivable
Content must be presentable in ways users can perceive.
### 1.1 Text Alternatives
#### 1.1.1 Non-text Content (Level A)
All non-text content needs text alternatives.
```tsx
// Images
// Decorative images
// Complex images with long descriptions
The CEO reports to the board. Three VPs report to the CEO:
VP Engineering, VP Sales, and VP Marketing...
// Icons with meaning
// Icon buttons with visible text
```
### 1.2 Time-based Media
#### 1.2.1 Audio-only and Video-only (Level A)
```tsx
// Audio with transcript
View transcript
Full transcript text here...
// Video with captions
```
### 1.3 Adaptable
#### 1.3.1 Info and Relationships (Level A)
Structure and relationships must be programmatically determinable.
```tsx
// Proper heading hierarchy
Page Title
Section Title
Subsection
// Data tables with headers
Quarterly Sales Report
Product
Q1
Q2
Widget A
$10,000
$12,000
// Lists for grouped content
```
#### 1.3.5 Identify Input Purpose (Level AA)
```tsx
// Input with autocomplete for autofill
```
### 1.4 Distinguishable
#### 1.4.1 Use of Color (Level A)
```tsx
// Bad: Color only indicates error
// Good: Color plus icon and text
{hasError && (
This field is required
)}
```
#### 1.4.3 Contrast (Minimum) (Level AA)
```css
/* Minimum contrast ratios */
/* Normal text: 4.5:1 */
/* Large text (18pt+ or 14pt bold+): 3:1 */
/* Good contrast examples */
.text-on-white {
color: #595959; /* 7:1 ratio on white */
}
.text-on-dark {
color: #ffffff;
background: #333333; /* 12.6:1 ratio */
}
/* Link must be distinguishable from surrounding text */
.link {
color: #0066cc; /* 4.5:1 on white */
text-decoration: underline; /* Additional visual cue */
}
```
#### 1.4.11 Non-text Contrast (Level AA)
```css
/* UI components need 3:1 contrast */
.button {
border: 2px solid #767676; /* 3:1 against white */
background: white;
}
.input {
border: 1px solid #767676;
}
.input:focus {
outline: 2px solid #0066cc; /* Focus indicator needs 3:1 */
outline-offset: 2px;
}
/* Custom checkbox */
.checkbox {
border: 2px solid #767676;
}
.checkbox:checked {
background: #0066cc;
border-color: #0066cc;
}
```
#### 1.4.12 Text Spacing (Level AA)
Content must not be lost when user adjusts text spacing.
```css
/* Allow text spacing adjustments without breaking layout */
.content {
/* Use relative units */
line-height: 1.5; /* At least 1.5x font size */
letter-spacing: 0.12em; /* Support for 0.12em */
word-spacing: 0.16em; /* Support for 0.16em */
/* Don't use fixed heights on text containers */
min-height: auto;
/* Allow wrapping */
overflow-wrap: break-word;
}
/* Test with these values: */
/* Line height: 1.5x font size */
/* Letter spacing: 0.12em */
/* Word spacing: 0.16em */
/* Paragraph spacing: 2x font size */
```
#### 1.4.13 Content on Hover or Focus (Level AA)
```tsx
// Tooltip pattern
function Tooltip({ content, children }) {
const [isVisible, setIsVisible] = useState(false);
return (
e.key === 'Escape' && setIsVisible(false)}
// Hoverable: content stays visible when pointer moves to it
onMouseEnter={() => setIsVisible(true)}
onMouseLeave={() => setIsVisible(false)}
// Persistent: stays until trigger loses focus/hover
>
{content}
)}
);
}
```
## Principle 2: Operable
Interface components must be operable by all users.
### 2.1 Keyboard Accessible
#### 2.1.1 Keyboard (Level A)
All functionality must be operable via keyboard.
```tsx
// Custom interactive element
function CustomButton({ onClick, children }) {
return (
);
}
// Better: just use a button
function BetterButton({ onClick, children }) {
return ;
}
```
#### 2.1.2 No Keyboard Trap (Level A)
```tsx
// Modal with proper focus management
function Modal({ isOpen, onClose, children }) {
const closeButtonRef = useRef(null);
// Return focus on close
useEffect(() => {
if (!isOpen) return;
const previousFocus = document.activeElement;
closeButtonRef.current?.focus();
return () => {
(previousFocus as HTMLElement)?.focus();
};
}, [isOpen]);
// Allow Escape to close
useEffect(() => {
const handleKeyDown = (e: KeyboardEvent) => {
if (e.key === 'Escape') onClose();
};
document.addEventListener('keydown', handleKeyDown);
return () => document.removeEventListener('keydown', handleKeyDown);
}, [onClose]);
return (
{children}
);
}
```
### 2.4 Navigable
#### 2.4.1 Bypass Blocks (Level A)
```tsx
// Skip links
Skip to main contentSkip to navigation...
{/* Main content */}
```
#### 2.4.4 Link Purpose (In Context) (Level A)
```tsx
// Bad: Ambiguous link text
Click hereRead more
// Good: Descriptive link text
View quarterly sales report
// Good: Context provides meaning
Quarterly Sales Report
Sales increased by 25% this quarter...
Read full report
// Good: Visually hidden text for context
Read more
about quarterly sales report
```
#### 2.4.7 Focus Visible (Level AA)
```css
/* Always show focus indicator */
:focus-visible {
outline: 2px solid var(--color-focus);
outline-offset: 2px;
}
/* Custom focus styles */
.button:focus-visible {
outline: none;
box-shadow: 0 0 0 3px var(--color-focus);
}
/* High visibility focus for links */
.link:focus-visible {
outline: 3px solid var(--color-focus);
outline-offset: 2px;
background: var(--color-focus-bg);
}
```
### 2.5 Input Modalities (New in 2.2)
#### 2.5.8 Target Size (Minimum) (Level AA) - NEW
Interactive targets must be at least 24x24 CSS pixels.
```css
/* Minimum target size */
.interactive {
min-width: 24px;
min-height: 24px;
}
/* Recommended size for touch (44x44) */
.touch-target {
min-width: 44px;
min-height: 44px;
}
/* Inline links are exempt if they have adequate spacing */
.link {
/* Inline text links don't need minimum size */
/* but should have adequate line-height */
line-height: 1.5;
}
```
## Principle 3: Understandable
Content and interface must be understandable.
### 3.1 Readable
#### 3.1.1 Language of Page (Level A)
```html
...
...
```
#### 3.1.2 Language of Parts (Level AA)
```tsx
The French phrase c'est la vie means "that's life."
```
### 3.2 Predictable
#### 3.2.2 On Input (Level A)
Don't automatically change context on input.
```tsx
// Bad: Auto-submit on selection
// Good: Explicit submit action
```
### 3.3 Input Assistance
#### 3.3.1 Error Identification (Level A)
```tsx
function FormField({ id, label, error, ...props }) {
return (
{error && (
{error}
)}
);
}
```
#### 3.3.7 Redundant Entry (Level A) - NEW
Don't require users to re-enter previously provided information.
```tsx
// Auto-fill shipping address from billing
function CheckoutForm() {
const [sameAsBilling, setSameAsBilling] = useState(false);
const [billing, setBilling] = useState({});
const [shipping, setShipping] = useState({});
return (
);
}
```
## Principle 4: Robust
Content must be robust enough for assistive technologies.
### 4.1 Compatible
#### 4.1.2 Name, Role, Value (Level A)
```tsx
// Custom components must expose name, role, and value
function CustomCheckbox({ checked, onChange, label }) {
return (
);
}
// Custom slider
function CustomSlider({ value, min, max, label, onChange }) {
return (
{
if (e.key === 'ArrowRight') onChange(Math.min(value + 1, max));
if (e.key === 'ArrowLeft') onChange(Math.max(value - 1, min));
}}
>
);
}
```
## Testing Checklist
```markdown
## Keyboard Testing
- [ ] All interactive elements focusable with Tab
- [ ] Focus order matches visual order
- [ ] Focus indicator always visible
- [ ] No keyboard traps
- [ ] Escape closes modals/dropdowns
- [ ] Enter/Space activates buttons and links
## Screen Reader Testing
- [ ] All images have alt text
- [ ] Form inputs have labels
- [ ] Headings in logical order
- [ ] Landmarks present (main, nav, header, footer)
- [ ] Dynamic content announced
- [ ] Error messages announced
## Visual Testing
- [ ] Text contrast at least 4.5:1
- [ ] UI component contrast at least 3:1
- [ ] Works at 200% zoom
- [ ] Content readable with text spacing
- [ ] Focus indicators visible
- [ ] Color not sole indicator of meaning
```
## Resources
- [WCAG 2.2 Quick Reference](https://www.w3.org/WAI/WCAG22/quickref/)
- [Understanding WCAG 2.2](https://www.w3.org/WAI/WCAG22/Understanding/)
- [Techniques for WCAG 2.2](https://www.w3.org/WAI/WCAG22/Techniques/)