What are ARIA attribute issues?

aria-attribute-issues page

The issue

A control with an ARIA role but an incomplete or invalid set of attributes looks right and doesn’t work for screen reader users. A custom checkbox without aria-checked can’t say whether it is checked, and a slider without aria-valuenow can’t say where it is set. Sighted testing never notices, because the screen doesn’t depend on ARIA.

The cause is the contract between a role and its attributes in the WAI-ARIA specification. Assigning a role replaces the element’s native meaning, and some roles need attributes to describe their state: role="checkbox" needs aria-checked, role="slider" needs aria-valuenow, role="combobox" needs aria-expanded. A value outside what the specification allows, such as aria-hidden="yes" instead of "true", isn’t a value the specification defines, so what a browser does with it can’t be relied on. WCAG 4.1.2 requires a component’s name, role and state to be exposed programmatically.

Scope

Each element with an ARIA role or attribute is checked on its own. The pattern usually comes from one component in a shared library, so fixing the component fixes every page that uses it.

How to check you have it

  • In probeo: the page reports aria-required-attr, “Required ARIA attributes must be provided”, or aria-valid-attr-value, “ARIA attributes must conform to valid values”. Related rules report misspelled attribute names (aria-valid-attr), invalid roles (aria-roles) and attributes a role doesn’t allow (aria-allowed-attr).
  • By hand: for each element with a role, look the role up in the WAI-ARIA specification and confirm it has the required states and properties, with allowed values.
  • With a tool: the accessibility pane in Chrome or Firefox DevTools shows the role and states each element exposes. Change the control’s state and confirm they update.

Probeo reads the page as it was captured, so it checks attribute values as they stand. Whether they change when someone uses the control has to be tested by using it.

The fix

Give every ARIA role its required attributes, with values the specification allows.

Add the missing attributes and bind them to the component’s state, so aria-checked changes when the checkbox is toggled and aria-expanded when the menu opens. Replace invalid values with allowed ones: "true" or "false" for booleans, "true", "false" or "mixed" for aria-checked, "off", "polite" or "assertive" for aria-live. Where a native element does the same job, such as <input type="checkbox"> or <button>, use it and drop the ARIA.

Done when: every role has its required attributes with valid values that follow the control’s state, and the check above comes back clean.

Do not

  • Do not add a role without checking which attributes it requires.
  • Do not use free-form strings in attributes that take a fixed set of values.
  • Do not add ARIA where a native HTML element already provides the meaning.

FAQ

Should we add ARIA to every element?

No. The first rule of ARIA is: do not use ARIA if a native HTML element provides the same semantics. A native <input type="checkbox"> already exposes checked state without any ARIA attributes. ARIA is only necessary when native HTML cannot express the needed semantics.

How do aria-live regions relate to ARIA attribute issues?

aria-live is an ARIA attribute that must use one of three values: ‘off’, ‘polite’, or ‘assertive’. Using an invalid value like ‘true’ or ‘yes’ means the region will not announce dynamic content changes to screen readers. The attribute is present but functionally broken.

How do we handle dynamic content that changes ARIA state?

ARIA attributes must reflect current component state at all times. When a checkbox toggles, aria-checked must update from ‘true’ to ‘false’ or vice versa. When an accordion opens, aria-expanded must change. Static ARIA attributes on dynamic components are a common source of attribute value mismatches.

Why does partial ARIA cause more problems than no ARIA?

Native HTML elements have built-in accessibility semantics. When you add a role, you override those defaults. If you then omit the required attributes for that role, you have replaced working semantics with incomplete ones. The assistive technology trusts the role declaration and expects the attributes that go with it.

Can automated tools catch all ARIA attribute issues?

Automated tools detect missing required attributes and invalid static values reliably. They cannot verify that attribute values update correctly during interaction. A checkbox might have aria-checked=“false” in the DOM but never update it when clicked. That failure requires manual or integration testing to find.

What is an easy ARIA attribute mistake to make?

Writing booleans the wrong way. ARIA boolean attributes accept ‘true’ and ‘false’ as string values, not JavaScript booleans and not ‘yes’/‘no’. Setting aria-hidden={`true`} in JSX works because React converts it, but setting aria-hidden=‘yes’ in HTML does not. yes isn’t a value the specification defines, so what a browser does with it can’t be relied on.

Which product detects this

Probeo checks this on every page of your site as part of Site Clarity. This page explains one instance; the product tells you every page that has it.