WCAG Compliance Patterns
When to Use
You need to make AJAX interactions accessible to keyboard users, screen reader users, and users with disabilities (WCAG 2.1 Level AA compliance).
Decision
| If you need... | Use... | Why |
|---|---|---|
| Screen reader announcements | AnnounceCommand or MessageCommand | WCAG 4.1.3 - users know content changed |
| Focus management | FocusFirstCommand | WCAG 2.4.3 - keyboard users maintain context |
| Keyboard access | keypress: TRUE in #ajax | WCAG 2.1.1 - keyboard-only users can trigger AJAX |
| Live region updates | aria-live attributes | WCAG 1.3.1 - announces dynamic changes |
| Loading indicators | Accessible progress messages | WCAG 2.2.1 - users know operation in progress |
Pattern
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\AnnounceCommand;
use Drupal\Core\Ajax\ReplaceCommand;
use Drupal\Core\Ajax\FocusFirstCommand;
use Drupal\Core\Ajax\MessageCommand;
public function ajaxCallback(array &$form, FormStateInterface $form_state) {
$response = new AjaxResponse();
// 1. Update content
$response->addCommand(new ReplaceCommand('#results', $updated_content));
// 2. Announce change to screen readers
$response->addCommand(new AnnounceCommand(
'Results updated with 5 new items',
'polite' // Use 'assertive' only for errors
));
// 3. Manage focus for keyboard users
$response->addCommand(new FocusFirstCommand('#results'));
return $response;
}
// Keyboard-accessible AJAX trigger
$form['trigger'] = [
'#type' => 'button',
'#value' => t('Load More'),
'#ajax' => [
'callback' => '::loadMore',
'wrapper' => 'results',
'keypress' => TRUE, // CRITICAL: enables ENTER/SPACE triggering
],
];
// Accessible loading indicator
$form['trigger']['#ajax']['progress'] = [
'type' => 'throbber',
'message' => t('Loading more results...'), // Read by screen readers
];
// ARIA live region for dynamic content
$form['results'] = [
'#type' => 'container',
'#attributes' => [
'id' => 'results',
'aria-live' => 'polite', // Announces content changes
'aria-atomic' => 'true', // Reads entire region on update
],
];
Reference: core/lib/Drupal/Core/Ajax/AnnounceCommand.php, core/lib/Drupal/Core/Ajax/FocusFirstCommand.php
Common Mistakes
- Not announcing AJAX updates → WCAG 4.1.3 violation; screen reader users don't know content changed
- Missing
keypress: TRUEon AJAX buttons → WCAG 2.1.1 violation; keyboard users can't trigger AJAX - Not managing focus after updates → Users lose context; use FocusFirstCommand or InvokeCommand('focus')
- Using 'assertive' aria-live unnecessarily → Interrupts screen readers; reserve for errors
- Missing loading indicators → Users don't know operation in progress (WCAG 2.2.1)
- Not testing with screen readers → Use NVDA (Windows), JAWS (Windows), or VoiceOver (Mac) to verify
See Also
- ← Previous: Response Caching | Next: Screen Reader Support
- Feedback Commands
- Reference: WCAG 2.1 Guidelines, Drupal Accessibility documentation