The right element

Choose the element that already does the work, and know exactly what you take on when you do not.

02of 16
≈ 12Min read
5Parts

What a button gives you

Each row is a line of code you owe if you pick the div — and a bug if you forget one. The fastest accessibility improvement available in most codebases is replacing clickable divs with buttons.

<button><div onclick>
In the accessibility treerole=button, with a namenothing — it is a generic container
Keyboard focusyes, in document orderno, until you add tabindex="0"
Enter and Spacefire a clicknothing, until you write a keydown handler
Disabled statedisabled — and it leaves the tab orderyou invent it, and remember the tab order
Inside a formsubmitsnothing
High-contrast mode, forced coloursstyled as a controlstyled as text

The elements worth knowing by heart

and what they mean, not what they look like
<button>      something happens on this page
<a href>      you go somewhere
<label>       this text names that control
<fieldset>    these controls belong together, and <legend> names the group
<table>       data in rows and columns, with <th scope> and a <caption>
<ul> <ol>     a list — and a screen reader announces how many items
<nav> <main>  landmarks, so the page can be skimmed
<details>     a disclosure, with keyboard support already written
<dialog>      a modal, with focus handling and Escape already written
A link is not a button

If it changes the URL, it is a link — and it must work with middle-click, Cmd-click and "open in new tab". If it acts on this page, it is a button. <a href="#" onclick> is the worst of both: it looks like a link, navigates nowhere, and breaks the back button.

What the tree looks like

the same visual result, two different pages
<div class="card">
  <div class="title">Vesper</div>
  <div class="btn" onclick="add()">Add to the quote</div>
</div>

<!-- what a screen reader has to work with: "Vesper. Add to the quote." as plain text,
     with no way to reach or press the second one. -->

<article class="card">
  <h3>Vesper</h3>
  <button type="button" onclick="add()">Add to the quote</button>
</article>

<!-- article → heading "Vesper" → button "Add to the quote", reachable by Tab,
     listed when the user asks for every button on the page. -->

When you genuinely have to build it

Some controls have no HTML element: a combobox with a filtered list, a tree, a data grid. Those are the cases ARIA exists for, and they are covered later in this course. The rule is to reach for them after checking that no element already does it — which it usually does, and with the keyboard support already written.

if you must, you owe all of it
<div role="button" tabindex="0"
     onclick="add()"
     onkeydown="if (event.key === 'Enter' || event.key === ' ') { event.preventDefault(); add(); }">
  Add to the quote
</div>

The quiet ones

  • <b> and <i> are visual; <strong> and <em> carry emphasis. Screen readers mostly do not announce either — but the semantic pair survives a redesign.
  • A <p> is a paragraph; two <br>s are not. Structure is what lets somebody navigate by paragraph.
  • <span> and <div> mean nothing on purpose — that is what makes them the right choice for styling hooks and the wrong one for controls.
  • An <h3> that is only there to be bold is a heading in the page outline, and it will confuse somebody navigating by heading. Style a <p>.

Practice