Accessibility starts with the right element — use real buttons, links, headings, and landmarks so the browser gives you keyboard support and screen-reader meaning for free.
Why: the single highest-impact a11y habit is choosing the right element. A real <button> is focusable, fires on Enter and Space, and announces itself as "button" — all for free. A <div> styled to look like a button gives you none of that. Note: if it navigates to a URL it is a link (<a>); if it performs an action it is a <button>.
<!-- ❌ A div that looks clickable but isn't a real control -->
<div class="btn" onclick="save()">Save</div>
<!-- ✅ A real button: focusable, keyboard-operable, announced as "button" -->
<button type="button" onclick="save()">Save</button>
<!-- ✅ Going somewhere? That's a link, not a button -->
<a href="/settings">Settings</a>Why: landmark elements label the major regions of a page so screen-reader users can jump straight to "main" or "navigation" instead of wading through everything. They replace a soup of <div>s with meaning. Note: there should be exactly one <main> per page.
<body>
<header> <!-- logo, top nav -->
<nav aria-label="Primary">…</nav>
</header>
<main> <!-- the unique, primary content of this page -->
<article>…</article>
</main>
<aside>…</aside> <!-- related/secondary content -->
<footer>…</footer> <!-- site info, links -->
</body>Why: screen-reader users navigate by jumping heading to heading, so headings must form a real outline — one <h1> for the page, then <h2> sections, <h3> subsections — without skipping levels. Note: never pick a heading level for how big it looks; size is CSS's job, order is HTML's job.
<!-- ❌ Skips from h1 to h4 just to get smaller text -->
<h1>Dashboard</h1>
<h4>Recent activity</h4>
<!-- ✅ A logical outline; style the size separately in CSS -->
<h1>Dashboard</h1>
<h2>Recent activity</h2>
<h3>Today</h3>Why: a screen reader can't see an image, so it reads the alt attribute instead. Describe the image's purpose, not the word "image". If a picture is purely decorative, give it an empty alt="" so the reader skips it entirely. Note: a missing alt makes the reader announce the file name — usually meaningless.
<!-- Informative: describe what it conveys -->
<img src="/chart.png" alt="Sales rose 40% from March to June" />
<!-- Decorative: empty alt so it's skipped, not read as a filename -->
<img src="/swirl.svg" alt="" />