Semantic HTML
Use correct HTML elements to convey meaning and structure before reaching for ARIA attributes.
In this article
Semantic HTML
Problem
I once audited a site where everything was a div: buttons, navigation, main content, footer. Screen readers couldn’t tell any of it apart, so the whole page sounded like one long, unstructured blob.
Screen reader users move around a page by jumping between landmarks, such as the main content or the navigation, but when everything is a div, there are no landmarks. Users have to listen through your entire page from the top to find what they need.
Those div buttons don’t work with keyboards either. Tab doesn’t focus them, Enter doesn’t click them, and screen readers don’t announce them as interactive, so users don’t know they’re clickable.
Solution
Each HTML element has a job, and using it for that job sounds obvious, but we forget all the time.
<button> is for clickable actions, <a> for links, <nav> for navigation, <main> for primary content, and <header>/<footer> for those sections. <article> is for standalone content, <aside> for secondary content, and <h1> through <h6> for heading hierarchy. <table> is for tabular data (not layout), and <form> with proper <label> elements is for inputs.
You get the accessibility for free. A <button> announces as “button” to screen readers, responds to Enter and Space keys, and receives keyboard focus, all without any JavaScript or ARIA.
Example
This is a page built with semantic structure: landmarks, headings, and interactive elements that work without extra code.
Semantic Document Structure
<body>
<header>
<h1>Site Title</h1>
<nav aria-label="Primary">
<ul>
<li><a href="/">Home</a></li>
<li><a href="/about">About</a></li>
</ul>
</nav>
</header>
<main>
<article>
<header>
<h2>Article Title</h2>
<time datetime="2026-01-01">January 1, 2026</time>
</header>
<p>Introduction paragraph...</p>
<h3>First Section</h3>
<p>Section content...</p>
<figure>
<img src="chart.png" alt="Sales data visualization">
<figcaption>Q4 2025 Sales Performance</figcaption>
</figure>
<aside>
<h4>Related Information</h4>
<p>Additional context...</p>
</aside>
</article>
</main>
<aside aria-label="Sidebar">
<h2>Popular Posts</h2>
<ul>
<li><a href="/post-1">First Post</a></li>
</ul>
</aside>
<footer>
<p>© 2026 Company Name</p>
<nav aria-label="Footer">
<a href="/privacy">Privacy</a>
<a href="/terms">Terms</a>
</nav>
</footer>
</body>
Semantic Interactive Elements
Native elements provide keyboard and screen reader support that div-based alternatives require extensive code to replicate:
<!-- Div button requires extensive ARIA and JavaScript -->
<div role="button" tabindex="0" onclick="handleClick()"
onkeydown="handleKeyPress(event)">Submit</div>
<!-- Semantic button works automatically -->
<button type="submit">Submit</button>
<!-- Div link breaks keyboard nav and right-click -->
<div class="link" onclick="navigate('/page')">Go to page</div>
<!-- Semantic link has full browser features -->
<a href="/page">Go to page</a>
Semantic Form Elements
Proper form markup provides automatic validation, keyboard support, and screen reader announcements:
<form>
<label for="username">Username</label>
<input id="username" type="text" required>
<fieldset>
<legend>Shipping Address</legend>
<label for="street">Street</label>
<input id="street" type="text">
<label for="city">City</label>
<input id="city" type="text">
</fieldset>
<button type="submit">Submit</button>
<button type="button">Cancel</button>
</form>
Semantic Data Presentation
Tables with proper headers allow screen readers to announce cell relationships, and details/summary creates accessible disclosure widgets:
<table>
<caption>Monthly Sales Report</caption>
<thead>
<tr>
<th scope="col">Month</th>
<th scope="col">Revenue</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">January</th>
<td>$50,000</td>
</tr>
</tbody>
</table>
<details>
<summary>Advanced Settings</summary>
<p>Additional configuration options...</p>
</details>
Benefits
- Screen readers just work, announcing “navigation landmark” or “button” without any ARIA attributes.
- Search engines can read your content structure from the headings and landmarks, which helps SEO.
- Keyboard navigation works by default, with buttons responding to Enter and Space without custom JavaScript.
- Reader mode and text-to-speech features parse your document structure correctly.
- Less code to write: a
<button>does in one line what a div withrole="button",tabindex, and keyboard handlers takes twenty lines to achieve. - Self-documenting code:
<nav>tells you it’s navigation, while<div class="nav-wrapper">tells you nothing.
Tradeoffs
- You have to learn HTML properly: there are dozens of semantic elements, and knowing when to use each takes time.
- Default browser styles often clash with your designs, and buttons come with borders and backgrounds you’ll need to reset.
- Some elements have counterintuitive rules:
<address>is for contact information about the page or its nearest<article>, not for any postal address that appears in the content. Ask me how I learned that. - Heading levels follow hierarchy rules that can conflict with visual design, so you can’t jump from
<h1>to<h4>just because you want smaller text. - CSS frameworks often assume div-based structures, and third-party components render divs you can’t change without forking.
- Retrofitting semantic HTML into an existing div-soup codebase is painful, and it’s easier to start with the right elements than to fix them later.
- You can’t see whether the markup is semantically correct by looking at the page in a browser, so checking it takes accessibility audits and screen reader testing.
Summary
Using HTML elements for their intended purpose gives you accessibility, keyboard support, and SEO benefits without extra code. A <button> works with keyboards and screen readers automatically, while a styled <div> needs a lot of JavaScript and ARIA to get close to the same behavior. Picking the right element first, and adding ARIA only where HTML has no element for the job, makes pages work better for everyone.
See also
- ARIA Roles and Attributes — Accessibility
- Accessible Forms — Accessibility
- Semantic HTML - MDN
- HTML5 Semantic Elements - W3Schools
- Accessibility and Semantics - web.dev