Accessibility beyond the basics (ARIA, focus, contrast) — Ops Runbook — Practical Guide (May 26, 2026)
body { font-family: Arial, sans-serif; line-height: 1.6; margin: 2rem; max-width: 800px; }
h2, h3 { margin-top: 2rem; }
p.audience { font-weight: bold; font-size: 1.2rem; color: #555; }
pre { background: #f5f7fa; border: 1px solid #ddd; padding: 1rem; overflow-x: auto; }
code { font-family: ‘Source Code Pro’, monospace; }
ul { margin-left: 1.5rem; }
.social { margin-top: 3rem; font-style: italic; color: #888; }
Accessibility beyond the basics (ARIA, focus, contrast) — Ops Runbook
Level: Intermediate to Experienced Software Engineers
As of 26 May 2026, guidance targets HTML5 and ARIA 1.2 and assumes evergreen browsers from 2023 onwards.
Prerequisites
This guide expects familiarity with core web accessibility fundamentals, including semantic HTML, keyboard navigation principles, and WCAG 2.1 success criteria. Prior exposure to ARIA basics (roles, states, properties), CSS focus management, and colour contrast are essential.
It covers how to go beyond initial ARIA usage, focusing on robust, maintainable, and performant implementations relevant for modern web apps and complex UI components.
Hands-on steps
1. Master ARIA roles and properties contextually
ARIA is not a blanket fix — misusing roles or properties can confuse assistive technologies or degrade usability. Use ARIA only when semantic HTML lacks needed functionality.
Example: Enhance a custom toggle button that cannot use a <button> element directly because it involves complex inner structures.
<div role="switch"
tabindex="0"
aria-checked="false"
aria-label="Enable notifications"
id="notif-toggle"> ... </div>
Note that role="switch" is more appropriate than a generic button for toggle state conveyance. Always match aria-checked with the actual visual toggle state programmatically.
2. Robust Focus Management
Proper keyboard focus is critical for usability beyond basic tabbing. Avoid focus traps or confusing focus order by:
- Ensuring logical DOM order matches visual order.
- Using
tabindex="0"for programmatically focusable elements; avoid positive tabindex values as they break natural flow. - Managing focus programmatically in modal dialogs, drawers, and other overlays — focus should move inside when opened and return on close.
Example: trap focus in a modal dialog using JavaScript:
const focusableElementsSelector = 'a[href], button, textarea, input, select, [tabindex]:not([tabindex="-1"])';
const modal = document.getElementById('my-modal');
const firstFocusable = modal.querySelectorAll(focusableElementsSelector)[0];
const focusableContent = modal.querySelectorAll(focusableElementsSelector);
const lastFocusable = focusableContent[focusableContent.length - 1];
modal.addEventListener('keydown', function(e) {
if(e.key === 'Tab') {
if(e.shiftKey) { // Shift + Tab
if(document.activeElement === firstFocusable) {
e.preventDefault();
lastFocusable.focus();
}
} else { // Tab
if(document.activeElement === lastFocusable) {
e.preventDefault();
firstFocusable.focus();
}
}
}
});
When to choose a JavaScript focus trap library vs. rolling your own: For complex applications, tested libraries like focus-trap reduce error risk. For small cases, custom code may suffice.
3. Advanced colour contrast and non-colour indicators
Beyond simple contrast ratios, consider states such as hover, focus, active, disabled, and error states, which may require different contrast levels.
Use tools that measure contrast against the background dynamically, supporting transparent layers and multiple backgrounds (SVG, gradients).
Always provide non-colour cues for important states — for example, error messages should include icons or text markers alongside red colour:
<label for="email">Email address</label>
<input type="email" id="email" aria-describedby="email-error" aria-invalid="true" />
<span id="email-error" role="alert">⚠ Please enter a valid email address.</span>
ARIA live regions (here, role="alert") announce errors to screen readers immediately.
4. Use live regions thoughtfully
Dynamic content updates (e.g. form validation, chat messages) should be communicated through ARIA live regions without moving focus. Use aria-live="polite" or aria-live="assertive" based on urgency.
Example for asynchronous status:
<div aria-live="polite" id="status-message"></div>
Update the element’s text programmatically on status changes.
Common pitfalls
- Overusing ARIA: Native elements are often better. E.g., don’t use
role="button"on a <div> when a <button> exists. - Positive tabindex: Avoid using
tabindex="1"or higher; it confuses keyboard navigation order. - Poor focus feedback: Custom focus styles sometimes lack visible outlines, leaving keyboard users lost.
- Insufficient colour contrast in complex UI states: Consider dark mode, transparent layers, and inactive states carefully.
- Erroneous live region usage: Prevent screen reader overload by avoiding rapid-fire updates or incorrect role assignment.
Validation
Validation should combine automated and manual testing:
- Automated tools: Use WAVE, a11y Checklist, or browser devtools accessibility inspectors.
- Keyboard testing: Navigate entire UI without mouse, test keyboard traps and focus order.
- Screen reader testing: NVDA (Windows), VoiceOver (macOS/iOS), TalkBack (Android).
- Colour contrast checks: Tools like Contrast Ratio or integrated devtools colour pickers.
Checklist / TL;DR
- Use ARIA only when native HTML semantics insufficient; prefer semantic tags.
- Apply roles and states correctly (match aria-checked, aria-expanded with UI state).
- Manage keyboard focus without positive tabindex; trap focus in modals responsibly.
- Ensure visible and customisable focus outlines; never disable them without replacement.
- Maintain 4.5:1 contrast ratio minimum for normal text and adapt for UI states.
- Use non-colour indicators for state changes (error, success, warnings).
- Deploy live regions selectively and monitor for screen reader overload.
- Validate accessibly using combination of automated and assistive technology testing.
References
- WAI-ARIA 1.2 Specification (W3C)
- Web Content Accessibility Guidelines (WCAG) 2.1 & 2.2 (W3C)
- ARIA Guide on MDN Web Docs
- Managing Focus with Keyboard (MDN)
- WCAG 2.2 Contrast Minimum
- <a href="https://dequeuniversity.com/rules/axe/4.8/aria-allowed-attr" target