/ HTML Checker Fixes / ARIA Errors

How to Fix ARIA Errors

ARIA (Accessible Rich Internet Applications) lets you add semantic meaning to HTML when native elements don't suffice. Used correctly, it makes complex interactive widgets accessible. Used incorrectly, it actively harms accessibility — and most ARIA usage is incorrect. The first rule of ARIA is "don't use ARIA". The HTML Checker flags ARIA errors; this guide walks through fixing them and the broader principle of preferring native HTML.

1. The first rule of ARIA

If a native HTML element exists with the semantics and behaviour you need, use the native element.

<!-- WRONG: reinventing button -->
<div role="button" tabindex="0" onclick="...">Submit</div>

<!-- RIGHT: use the native button -->
<button type="button" onclick="...">Submit</button>

The native <button> handles keyboard (Enter, Space), focus management, screen-reader announcement, and disabled state — all for free. The div role="button" needs all of this re-implemented manually, and people get it wrong.

2. Audit your ARIA

Step 1
Run the HTML Checker
Filter to ARIA findings. Common errors:
  • role="presentaton" (typo for presentation)
  • role="button" on a <button> (redundant)
  • aria-label repeating visible text (overrides visible label)
  • Missing required ARIA: aria-expanded on disclosure widgets, aria-controls on tab triggers
  • aria-labelledby pointing at non-existent ID

3. Common ARIA patterns and their fixes

Pattern: Custom checkbox

<!-- WRONG -->
<div role="checkbox" onclick="toggle(this)">Subscribe</div>

<!-- RIGHT (native) -->
<label>
  <input type="checkbox" name="subscribe">
  Subscribe
</label>

<!-- IF YOU MUST use a custom checkbox (e.g. for styling) -->
<div role="checkbox" 
     tabindex="0" 
     aria-checked="false" 
     onclick="toggle(this)" 
     onkeydown="if(event.key === ' ' || event.key === 'Enter') toggle(this)">
  Subscribe
</div>

Pattern: Disclosure widget (expand/collapse)

<!-- RIGHT -->
<button type="button" 
        aria-expanded="false" 
        aria-controls="advanced-options">
  Advanced options
</button>
<div id="advanced-options" hidden>
  ...options...
</div>

<!-- Toggle aria-expanded and the hidden attribute together -->

Pattern: Navigation landmark

<!-- WRONG: reinventing nav -->
<div role="navigation" aria-label="Main">...</div>

<!-- RIGHT -->
<nav aria-label="Main">...</nav>

<nav> implies role="navigation". Adding it explicitly is redundant.

Pattern: Live region

<!-- For dynamic content that updates -->
<div role="status" aria-live="polite">
  3 items added to cart
</div>

<!-- For urgent updates -->
<div role="alert" aria-live="assertive">
  Error: payment declined
</div>

4. Fix aria-label misuse

⚠️ aria-label overrides the visible text for screen readers. If a button says "Submit" and has aria-label="Submit form", sighted users see "Submit" but screen-reader users hear "Submit form". Worse, when copy changes the aria-label drifts.

Only use aria-label when there's NO visible text:

<!-- Icon-only button -->
<button aria-label="Close">
  <svg>...x icon...</svg>
</button>

<!-- Link that just says "More" - use aria-label to disambiguate -->
<a href="/aipageseo-demo-pages/how-to-fix-aria-errors.html" aria-label="Read more about pricing">
  More &rarr;
</a>

5. ARIA design patterns reference

For complex widgets, follow the ARIA Authoring Practices Guide exactly. The patterns cover:

Half-implementing a pattern is worse than not using ARIA at all. The patterns include required keyboard handling, focus management, and specific ARIA attributes — all of which must be present together.

6. Test with assistive technology

HTML validation passing isn't the same as accessibility working. Test with:

💡 Many ARIA "errors" are actually correct ARIA used with elements that don't need it. The fix is often removing ARIA, not adding more.

📐 Re-run the HTML Checker

Verify ARIA errors are cleared.

Run HTML Checker →
Related Guides: HTML Checker Fixes  ·  Accessibility Fixes  ·  Fix Form Validation  ·  HTML Checker Guide
💬 Got a problem?