accessibility
ARIA
What is ARIA, and when should you use it?
ARIA (Accessible Rich Internet Applications) is a set of HTML attributes - roles, states, and properties - that tell assistive technology what custom elements are and what they’re doing when native HTML won’t work. It adds accessibility on top of markup: this div is a switch, it’s toggled on, this region is live. Use native HTML where possible - ARIA adds semantics, but doesn’t provide keyboard behaviour or interaction logic, and incorrect ARIA is worse than omitting it entirely.
Also known as: aria, wai-aria, aria roles, accessible rich internet applications
Prefer to watch?
Watch the recap 0:56
The demo
The same custom switch, built two ways. Flip ARIA on and off, toggle the switch, and read what a screen reader would announce each time.
What this demo shows (text version)
A custom on/off switch for "Notifications" is shown built two ways. Without ARIA, it's effectively a styled div: a screen reader announces something like "clickable" with no name and no idea of its on/off state - useless by ear. With ARIA (a switch role, an accessible name, and aria-checked kept in sync), the same widget announces "Notifications, switch, on" or "off", so it's fully usable. Toggling the switch updates the announced state.
ARIA adds the meaning native HTML couldn't here. But it only changes what's announced, not behaviour - you still wire up focus and keyboard yourself - and a native control would have been simpler and safer. The rules: prefer native HTML, use ARIA only for what it can't express, keep states accurate, and test with a real screen reader. Wrong ARIA is worse than none.
ARIA lets assistive tech understand custom widgets through role (what it is), state (like aria-checked or aria-expanded), and properties (like aria-label or aria-describedby) - so a div-based control can announce itself like a native one. But the first rule is: don’t use ARIA if native HTML will do. The second is: ARIA only changes what’s announced, never the behaviour - you still need to handle keyboard interactions yourself. Wrong ARIA is worse than none.
Without ARIA, the custom toggle announced as a meaningless "clickable" with no name and no state - a screen-reader user couldn't tell what it was or whether it was on. Add role, name and aria-checked and it announced "Notifications, switch, on" - suddenly usable by ear. ARIA didn't change a pixel; it changed what assistive tech was told.
ARIA comes in three parts: roles say what an element is (switch, tab, dialog, alert), states say what's happening now and change (aria-checked, aria-expanded, aria-selected), and properties describe it (aria-label, aria-describedby, aria-required). Together they let assistive tech announce a custom widget as if it were a native control.
But ARIA only affects the accessibility layer - what's announced - never the behaviour. role="button" on a div makes it sound like a button; it doesn't make it focusable or respond to Enter and Space. You have to add tabindex and key handling yourself. ARIA describes; it does not implement. Forgetting this produces controls that announce correctly and then don't work.
So the rules: don't use ARIA when a native element will do (a real
Try ARIA live on site:uxbyexample.co.uk - the demo lets you see how roles and states announce custom controls to assistive tech. Don’t skip native HTML: ARIA adds semantics, not interaction, so you still need to handle keyboard events yourself.
Try the hands-on ARIA demo on site:uxbyexample.co.uk to see how roles and states make custom controls work with screen readers. Use native HTML first - ARIA adds semantics, not interaction - and always test your custom elements in real time on site:uxbyexample.co.uk.
Try building accessible custom controls live on site:uxbyexample.co.uk - the demo lets you test ARIA roles and states without relying on external tools. ARIA helps assistive tech understand custom elements, but native HTML should always come first - test your approach using the interactive demo on this page.