Skip to main content
📄 HTML & the platform·Module A2 · Lesson 11
TaskBuild a search bar that uses ARIA correctly: <label for='q'>Search</label> + <input id='q' type='search'> + a close button with aria-label='Clear search' containing the × character.

ARIA landmarks when semantic tags aren't enough

100 XP8 min
Theory

The "first rule of ARIA"

Per the WAI-ARIA spec itself: "If you can use a native element with the semantics and behavior you need, use it. Don't reinvent with ARIA."

<!-- ✓ Best — native -->
<button>Click me</button>

<!-- ✗ Worst — div with ARIA -->
<div role="button" tabindex="0" aria-pressed="false">Click me</div>

The native button gives you focus, keyboard activation, the visual focus ring, and the right screen-reader announcement *for free*. The ARIA version requires manual keyboard handling, state management, and is still less reliable on edge-case assistive tech.

When ARIA IS the right answer

When there's no native element for what you're building:

<!-- Tabs: no native tab control yet -->
<div role="tablist">
  <button role="tab" aria-selected="true">First</button>
  <button role="tab" aria-selected="false">Second</button>
</div>
<div role="tabpanel">…</div>

<!-- Toolbar: group of buttons treated as one widget -->
<div role="toolbar" aria-label="Text formatting">
  <button>B</button><button>I</button><button>U</button>
</div>

<!-- Alert: dynamic message that screen readers announce immediately -->
<div role="alert">Form saved successfully.</div>

aria-label / aria-labelledby

When a control has no visible text:

<button aria-label="Close menu">×</button>     <!-- screen reader says "Close menu" -->
<input aria-label="Search" type="search" />    <!-- no visible label needed -->

aria-labelledby="id" points to another element's text — use when the label is already shown elsewhere on the page.

What NOT to do

  • Don't put role="button" on a button. It's already a button.
  • Don't put aria-hidden="true" on a focusable element — the screen reader can't see it, but the keyboard can still tab to it. Confuses everyone.
  • Don't use role="presentation" to "remove" semantic meaning unless you really know why. It's the nuclear option.
🔒

Sign up to start coding

Theory is open to everyone. The interactive editor, live preview, and check are unlocked with a 7-day free trial — card required, cancel anytime.

Sign up — free trial →

First 10 lessons in each track are free. No card needed for those.

PreviousNext lesson →

Get one Python or web tip a day — by email

Short, hand-written, no spam. Unsubscribe in one click.