Semantic HTML & Accessibility
Learn how to use meaningful HTML elements that help browsers, search engines, and screen readers understand your page — and why that matters for every user.
Imagine you receive a parcel in the post. The box is completely unlabelled — no indication of what is fragile, which side is up, or who it is for. You could figure it out by opening everything, but it is slow and error-prone. Now imagine the same parcel with clear labels: "FRAGILE", "THIS SIDE UP", "For: Reception". Suddenly anyone who touches that box knows exactly what to do.
HTML elements work the same way. You can build an entire page out of <div> and <span> tags — and it will look fine — but nobody useful gets any labels: not the browser, not a search engine, and not a screen reader used by someone who cannot see the screen. Semantic HTML is the practice of choosing elements whose names describe the content inside them. It is one of the highest-value, lowest-effort improvements you can make as a web developer.
#Semantic vs Non-Semantic Elements
A semantic element carries meaning in its name. <nav> means "this is a navigation menu". <article> means "this is a self-contained piece of content". <button> means "the user can press this".
A <div> means absolutely nothing on its own — it is a generic container with no implied role. Using only <div> tags to build a page is affectionately called div soup. Here is the same page skeleton written two ways:
<!-- DIV SOUP: generic, meaningless to machines -->
<div class="header">
<div class="nav">...</div>
</div>
<div class="main">
<div class="article">...</div>
<div class="sidebar">...</div>
</div>
<div class="footer">...</div><!-- SEMANTIC HTML: self-documenting and accessible -->
<header>
<nav>...</nav>
</header>
<main>
<article>...</article>
<aside>...</aside>
</main>
<footer>...</footer>A city with no street signs
Imagine a city where every road, alley, park, and car park looks identical — same grey concrete, no signs. You can still get around by memorising the layout, but newcomers are lost, emergency services struggle, and GPS is useless.
Semantic HTML is the city's street signs. <header>, <nav>, <main>, and <footer> are landmarks that let everyone — sighted users, assistive technology, and search engine bots — navigate your page instantly.
#The Core Landmark Elements
Here is a bird's-eye view of the seven workhorse semantic elements:
| Element | Purpose | |---|---| | <header> | Introductory content for the page or a section (logo, site title, top nav) | | <nav> | A set of navigation links | | <main> | The primary, unique content of the page — only one per page | | <section> | A thematic grouping that belongs to a larger whole | | <article> | Self-contained content that could stand alone (blog post, news story) | | <aside> | Content tangentially related to the main content (sidebars, pull quotes) | | <footer> | Closing content for the page or a section (copyright, contact links) |
`<article>` vs `<section>` in one sentence: if the content could be copy-pasted to another site and still make sense, use <article>. If it only makes sense as part of the current page, use <section>.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>The Daily Brew — Coffee Blog</title>
</head>
<body>
<header>
<h1>The Daily Brew</h1>
<nav>
<ul>
<li><a href="/">Home</a></li>
<li><a href="/recipes">Recipes</a></li>
</ul>
</nav>
</header>
<main>
<article>
<h2>Why Cold Brew Takes 12 Hours</h2>
<p>Unlike hot coffee, cold brew relies on time...</p>
</article>
<aside>
<h2>Related Posts</h2>
<ul><li><a href="/espresso">Espresso Basics</a></li></ul>
</aside>
</main>
<footer>
<p>© 2026 The Daily Brew</p>
</footer>
</body>
</html>#Accessibility & Alt Text
Roughly 1 in 6 people worldwide lives with some form of disability. Many browse the web using screen readers — software that reads page content aloud. Screen readers treat semantic elements as landmarks that users can jump between with a single keypress.
A screen reader user can skip directly to <main>, bypassing the header and navigation they have already heard. Without semantic markup, there are no landmarks — they must listen to every link and heading from the very top, on every page load.
Images are invisible to screen readers unless you describe them with an alt attribute. Write alt text that describes what the image shows — not its file name, not the word "image".
<!-- Too vague — tells the user nothing -->
<img src="coffee.jpg" alt="image">
<!-- Just right — paints a picture -->
<img src="coffee.jpg" alt="A glass of iced cold brew coffee on a wooden table">
<!-- Decorative only — leave alt empty so screen readers skip it -->
<img src="divider.png" alt="">Do not replace every div with a semantic element
Semantic elements are for content regions — they do not replace every layout <div>. If you need a flex container purely for visual alignment with no semantic meaning, a <div> is the correct choice. The rule of thumb is: content regions get semantic elements; layout helpers use divs.
Also remember: <main> should appear only once per page, and heading levels should always go in order (<h1> → <h2> → <h3>) — never skip levels just to change size. Use CSS for sizing.
A developer is marking up a self-contained news story that could be syndicated to another website unchanged. Which element is the best choice?
Key takeaways
- Semantic elements like <header>, <nav>, <main>, <article>, <aside>, and <footer> label what content *is* — not just where it sits on screen.
- Screen readers use these landmarks so users can skip directly to the content they need; div soup forces them to listen to everything from the top.
- Every meaningful image needs an alt attribute that describes what it shows; purely decorative images get an empty alt="".
- Use <article> for self-contained content and <section> for thematic chunks of a larger page — and keep <main> to one per page.
- Semantic HTML benefits users, assistive technology, and search engines simultaneously, making it one of the easiest high-impact improvements in web development.
A screen reader user loads this page and presses the key to jump between landmarks. What can they do that they could NOT do with a page built entirely of <div> tags?
<header>
<nav>...</nav>
</header>
<main>
<article>Why Cold Brew Takes 12 Hours...</article>
</main>
<footer>© 2026 The Daily Brew</footer>This code has a bug — what's wrong?
<img src="cold-brew.jpg" alt="image">Complete the tag so this self-contained blog post — one that could be syndicated to another site unchanged — uses the correct semantic element.
<main> <> <h2>Why Cold Brew Takes 12 Hours</h2> <p>Unlike hot coffee, cold brew relies on time...</p> </> </main>
Arrange these lines into a valid semantic page skeleton, from the top of the body to the bottom.
<main>...</main>
<nav>...</nav>
<header>
<footer>© 2026 The Daily Brew</footer>
</header>
The page below is built entirely out of divs (div soup). Rewrite it using proper semantic HTML. Make sure to: (1) replace structural divs with <header>, <nav>, <main>, <article>, <aside>, and <footer>; (2) add a meaningful alt attribute to the image; (3) add lang="en" to the <html> tag.
Try it live — edit the code and hit Run to see it rendered: