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 tree | role=button, with a name | nothing — it is a generic container |
| Keyboard focus | yes, in document order | no, until you add tabindex="0" |
| Enter and Space | fire a click | nothing, until you write a keydown handler |
| Disabled state | disabled — and it leaves the tab order | you invent it, and remember the tab order |
| Inside a form | submits | nothing |
| High-contrast mode, forced colours | styled as a control | styled as text |
The elements worth knowing by heart
<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
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
<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.
<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>.