Lesson 28 of 55 · HTML
Accessibility – ARIA Roles, Live Regions, and Keyboard Navigation
Duration: 12 min
Deep Dive into ARIA
When native HTML cannot convey the needed semantics, ARIA attributes fill the gap.
Modal dialog example
<div id='myModal' role='dialog' aria-modal='true' aria-labelledby='modalTitle'>
<h2 id='modalTitle'>Subscribe</h2>
<form>
<label for='email'>Email:</label>
<input type='email' id='email' required />
<button type='submit'>Send</button>
</form>
<button aria-label='Close' onclick='closeModal()'>✖</button>
</div>
role='dialog'tells assistive tech it’s a modal.aria-modal='true'traps focus inside the dialog.aria-labelledbylinks the dialog to its heading for a clear name.
Live region example
<div id='status' role='status' aria-live='polite'></div>
JavaScript can update #status with messages that screen readers will announce without interrupting the user.
Keyboard navigation best practices
- Ensure all interactive elements are reachable via Tab.
- Provide a visible focus outline (
:focus { outline: 2px solid #5b9dd9; }). - Allow closing modals with Esc and return focus to the element that opened the modal.
- Keep the tab order logical; avoid
tabindexvalues higher than 0 unless absolutely necessary.
ARIA for custom widgets
role='button'for<div>or<span>acting like a button.aria-pressedfor toggle buttons.aria-expandedfor expandable sections (accordions, menus).aria-controlsto indicate which element is being controlled.
Quick checklist for ARIA and keyboard
- Native elements used where possible? ✅
- ARIA roles added only when needed? ✅
- Accessible name provided (
aria-labelor visible text)? ✅ - State attributes (
aria-expanded,aria-pressed) kept in sync with UI? ✅ - Tested with a screen reader and accessibility validator? ✅
If any answer is “no”, refactor your markup before moving on.
Tip: Run the axe Chrome extension on your pages; it highlights missing ARIA attributes, insufficient color contrast, and focus‑order issues.