General
- Ensure sufficient colour contrast for all controls (minimum 3:1 for UI components)
- Do not rely on colour alone to indicate the current item — use size, shape, or other visual differences
- All navigation controls must be keyboard accessible
- Announce item changes to screen readers
- Provide clear labels for all controls
Web
Semantic markup
- Use <button> elements for previous/next controls
- Use <button> or <a> elements for individual indicators
- Wrap the stepper in a <nav> or an appropriate container
- Provide proper ARIA attributes for the carousel relationship
Key accessibility attributes:
- Previous/Next buttons: Use descriptive aria-label (e.g., "Previous item", "Next item")
- Indicators: Use aria-label to describe each one (e.g., "Go to item 2")
- Current indicator: Use aria-current="true" to mark the active item
- Disabled buttons: Use disabled attribute when appropriate (first to last pattern)
- Icons: Add aria-hidden="true" to decorative arrow icons
Carousel relationship
- Use aria-live="polite" on a region that announces item changes
- Announce the current item number and total (e.g., "Item 2 of 5")
- Update the announcement when users navigate to a new item
Keyboard navigation
- Tab — Move focus through stepper controls (previous button, indicators, next button)
- Enter or Space — Activate the focused control
- Arrow keys (optional) — Consider adding Left/Right arrow key support for previous/next navigation
- Home (optional) — Jump to first item
- End (optional) — Jump to last item
Focus management
- When navigating between items, consider whether to move focus to the newly displayed content
- For automatic carousels, ensure focus is not moved unexpectedly
- Use the appropriate tokens for indicator styling
Automatic rotation
If the stepper is used with an automatically rotating carousel:
- Provide a pause/play button
- Stop rotation when the user hovers, focuses, or interacts with the carousel
- Ensure automatic rotation does not move focus unexpectedly
React Native
- Use accessibilityRole="button" for previous/next controls
- Provide accessibilityLabel for all controls (e.g., "Previous item", "Next item", "Go to item 2")
- Use accessibilityState={{ disabled: true }} for disabled buttons (first to last pattern)
- Mark the current indicator with appropriate accessibility state
- Announce item changes to screen readers