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.

No signup required. Results in under 60 seconds.

What this check does

SiteCurl scans your pages for elements that use interactive ARIA roles: button, link, tab, and menuitem. For each one, it checks whether the element is actually reachable by keyboard. If a div has role='button' but no tabindex, keyboard users cannot focus or activate it. SiteCurl flags these.

The check also looks at elements with role='img' and verifies they have an accessible name via aria-label or aria-labelledby. Without a name, screen readers either skip the element or announce meaningless markup.

SiteCurl reports up to 10 issues per page, showing the element type and role so you know exactly 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 announce it correctly. But the role alone is not enough. The element also needs to respond to keyboard input: it must be focusable (via tabindex) and handle Enter and Space key events. Without those, a screen reader user hears 'button' but cannot press it.

This is one of the most common ARIA mistakes on the web. Developers add the role because it sounds right, then forget the keyboard side. The result is an element that works with a mouse but is completely 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 that the element is interactive. If the element cannot receive focus, the announcement is misleading. The user tries to activate it, nothing happens, and they have no way to tell why it failed.

Elements with role='img' have a different problem. They need an accessible name so screen readers can describe them. A decorative 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 announces '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 are doing something wrong.

Keyboard-only users face the same issue from a different angle. They press Tab to move through the page and never land on the element because it has no tabindex. The 'button' exists visually but is invisible to keyboard navigation.

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 announced as interactive but cannot be used. The first is a gap. The second is a trap.

Who this impacts most

Single-page applications and JavaScript-heavy sites are the most likely to have ARIA role issues. Custom dropdowns, modal dialogs, tab panels, and hamburger menus built from divs and spans often use ARIA roles without matching keyboard support.

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

Marketing sites with custom interactive elements (accordion sections, toggle buttons, animated 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 elements first. A real <button> element is focusable and handles keyboard events by default. A <a href> is focusable by default. Replace custom elements with their native HTML equivalents wherever you can. This eliminates most ARIA role issues at the source.

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

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

Step 4: Add accessible names to role='img' elements. If a div or span uses role='img', add aria-label='Description of the image' or aria-labelledby='id-of-label'. If the image is decorative, use role='presentation' instead.

Step 5: Test with keyboard only. Unplug your mouse and Tab through the page. Every element announced as interactive should receive focus and respond to Enter or Space. If you cannot reach or activate 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 correct cursor style. A native button tag gives you all of this for free.

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

Adding ARIA roles to elements that already have them. A button tag already has an implicit role of 'button.' Adding role='button' to it is redundant. It does no harm, but it clutters your markup and signals that the developer may not understand native semantics.

Using role='img' on decorative elements. If an element is purely decorative, 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