Part of the Accessibility audit

Check your ARIA role attributes

ARIA roles tell screen readers an element is interactive. But if that element is not keyboard-focusable, the role is a broken promise. SiteCurl finds the gaps.

Start 7-Day Studio Trial

No signup required. Results in under 60 seconds.

423,000+ checks run and counting

What this check does

SiteCurl scans your pages for tags that use ARIA roles like button, link, tab, and menuitem. For each one, it checks if the tag can be reached by keyboard. If a div has role='button' but no tabindex, keyboard users cannot focus or click it. SiteCurl flags these.

The check also looks at tags with role='img' and checks they have a name via aria-label or aria-labelledby. With no name, screen readers either skip the tag or read out blank markup.

SiteCurl reports up to 10 issues per page, showing the tag type and role so you know what to fix.

How this shows up in the real world

ARIA roles exist to fill gaps in HTML. If you need a div to act like a button, you add role='button' so screen readers read it right. But the role alone is not enough. The tag also needs to respond to keyboard input: it must be focusable (via tabindex) and handle Enter and Space keys. Without those, a screen reader user hears 'button' but cannot press it.

This is one of the most common ARIA mistakes on the web. Devs add the role because it sounds right, then forget the keyboard side. The result is a tag that works with a mouse but is fully dead to keyboard and screen reader users.

The same pattern applies to role='link', role='tab', and role='menuitem'. Each one tells the screen reader the tag is live. If the tag cannot get focus, the label misleads. The user tries to use it, nothing happens, and they have no way to tell why it failed.

Tags with role='img' have a new problem. They need a name so screen readers can describe them. A div with role='img' and no label leaves the user hearing 'image' with no context. If the image carries meaning, that meaning is lost.

Why it matters

ARIA roles set expectations. When a screen reader says 'button,' the user expects to press Enter and have something happen. When nothing happens, they are stuck. They do not know if the feature is broken or if they did something wrong.

Keyboard-only users face the same issue from a new angle. They press Tab to move through the page and never land on the tag because it has no tabindex. The 'button' exists on screen but is hidden from keyboard nav.

Getting ARIA wrong is worse than not using it at all. A div with no role is ignored by screen readers. A div with role='button' and no tabindex is read as live but cannot be used. The first is a gap. The second is a trap.

Who this impacts most

Single-page apps and JS-heavy sites are the most likely to have ARIA role issues. Custom dropdowns, modals, tab panels, and burger menus built from divs and spans often use ARIA roles with no matching keyboard support.

Sites using component libraries can inherit this problem. A third-party menu or tab widget may add roles to tags that are not natively focusable. If the library does not also manage focus, each use of that part has the same issue.

Marketing sites with custom live items (accordions, toggle buttons, cards that expand on click) often add role='button' to a div for styling reasons without adding keyboard handling.

How to fix it

Step 1: Use native HTML tags first. A real <button> tag is focusable and handles keyboard events by default. A <a href> is focusable by default. Swap custom tags for their native HTML forms where you can. This fixes most ARIA role issues at the source.

Step 2: Add tabindex='0' to custom live tags. If you must use a div or span with a live role, add tabindex='0' so keyboard users can reach it. This puts the tag in the normal tab order of the page.

Step 3: Add keyboard event handlers. Tags with role='button' must respond to Enter and Space. Tags with role='link' must respond to Enter. Add keydown listeners that fire the same action as the click handler.

Step 4: Add names to role='img' tags. If a div or span uses role='img', add aria-label='What the image shows' or aria-labelledby='id-of-label'. If the image is just for looks, use role='presentation' instead.

Step 5: Test with keyboard only. Unplug your mouse and Tab through the page. Each tag read as live should get focus and respond to Enter or Space. If you cannot reach or use it, it needs fixing.

Common mistakes when fixing this

Adding role='button' to a div and stopping there. The role is only half the work. You also need tabindex='0', a keydown handler for Enter and Space, and the right cursor style. A native button tag gives you all of this for free.

Using a positive tabindex value. Positive tabindex values override the natural tab order and cause nav to jump around. Always use tabindex='0' (normal order) or tabindex='-1' (script-only focus). Never use tabindex='1' or higher.

Adding ARIA roles to tags that already have them. A button tag already has a built-in role of 'button.' Adding role='button' to it is extra. It does no harm, but it clutters your markup and hints the dev may not grasp native semantics.

Using role='img' on visual-only tags. If a tag is just for looks, use role='presentation' or aria-hidden='true' to hide it from screen readers. Only use role='img' when the visual content carries meaning.

How to verify the fix

After making fixes, run another SiteCurl scan. The ARIA role issue count should drop to zero. For a manual check, open your browser's accessibility inspector (Chrome DevTools > Elements > Accessibility pane) and inspect each flagged element. It shows the computed role, name, and focusability state.

Tab through the page with your keyboard. Every element that looks interactive should receive visible focus and respond to Enter or Space. If you skip over an element or nothing happens when you press Enter, the fix is not complete.

The bottom line

ARIA roles tell screen readers what an element does. If the element is not keyboard-focusable, the role is misleading. Use native HTML elements when you can. When you cannot, add tabindex and keyboard handlers so the role matches the actual behavior.

Example findings from a scan

div[role='button'] missing tabindex on /contact

span[role='link'] not keyboard-focusable on /

div[role='img'] missing accessible name on /about

Frequently asked questions

What is an ARIA role?

An ARIA role tells screen readers what an element does. For example, role='button' says the element is a clickable button. Screen readers use this to announce the element correctly and tell users how to interact with it.

When should I use ARIA roles?

Only when native HTML does not fit your use case. A button tag is better than a div with role='button' because it handles focus and keyboard events automatically. Use ARIA roles as a last resort, not a first choice.

What is tabindex='0' and when do I need it?

tabindex='0' puts an element into the natural tab order so keyboard users can reach it. You need it on any non-native element (div, span) that has an interactive ARIA role. Without it, the element is announced as interactive but cannot be focused.

Can I check ARIA roles without signing up?

Yes. The free audit checks ARIA role usage as part of a full seven-category scan. No signup needed.

Check your ARIA roles now