Skip to content

Demo

What Aria actually does.

Every example below is real output captured from the published @aria-a11y/cli@0.2.0 running against these exact snippets — the diagnostics and the fixed code are verbatim, not hand-typed to look plausible. It’s static on purpose: a live in-browser approximation could drift from the CI-verified rule behaviour, and for a tool whose whole claim is “provably identical everywhere,” a demo that might show wrong output is worse than no demo.

Redundant role

no-redundant-role · format tier — auto-fixed

before
export const A = () => <button role="button">Save</button>;
after `aria fix`
export const A = () => <button>Save</button>;

aria check · error

Role 'button' is redundant: it matches the implicit role of <button>. Remove it.

Unsupported aria-*

no-unsupported-aria · format tier — auto-fixed

before
export const B = () => <button aria-checked="true">Go</button>;
after `aria fix`
export const B = () => <button>Go</button>;

aria check · error

'aria-checked' is not supported by role 'button' of <button>: WAI-ARIA defines no such property for the role, so user agents ignore it. Remove it.

Icon-only button, no name

control-needs-name · lint tier — reported, never auto-applied

before
export const C = () => <button><svg /></button>;
after `aria fix` — unchanged, by design
export const C = () => <button><svg /></button>;

aria check · warning

<button> is an interactive control (button) with no accessible name, so assistive technology cannot announce it (control-needs-name; WCAG 2.1 SC 4.1.2). Add text content, aria-label, or an associated <label>. A placeholder is not a name. Aria cannot write it for you.

Placeholder is not a name

control-needs-name · lint tier — reported, never auto-applied

before
export const D = () => <input type="text" placeholder="Search" />;
after `aria fix` — unchanged, by design
export const D = () => <input type="text" placeholder="Search" />;

aria check · warning

<input> is an interactive control (textbox) with no accessible name, so assistive technology cannot announce it (control-needs-name; WCAG 2.1 SC 4.1.2). Add text content, aria-label, or an associated <label>. A placeholder is not a name. Aria cannot write it for you.

Focusable ghost

aria-hidden-not-focusable · lint tier — reported, never auto-applied

before
export const E = () => <div aria-hidden="true"><button>x</button></div>;
after `aria fix` — unchanged, by design
export const E = () => <div aria-hidden="true"><button>x</button></div>;

aria check · warning

<div> has aria-hidden="true" but its hidden subtree still contains a focusable element (<button>), a focusable ghost (aria-hidden-not-focusable; WAI-ARIA 1.2). Remove aria-hidden, make the descendant non-focusable (tabindex="-1"), or move it out of the hidden subtree. Aria will not choose.

Run it yourself — the demo is one command away.

The honest interactive version of this page is your own codebase:

npx @aria-a11y/cli check src