Semantic HTML and Accessibility
Table of Contents
- What "Semantic" Means
- The Page Landmarks
- Sections, Articles, and Asides
- div and span: The Generic Elements
- Why Accessibility Matters
- Using the Keyboard
- Accessibility Checklist
- Restructure Your Page
- Try It Yourself
1. What "Semantic" Means
An element is semantic when its name tells you what it is, not
how it looks. <nav> means "navigation". <div> means nothing.
You could build an entire page from <div> elements and style it to
look identical to one built with proper elements. Visually, you
couldn't tell them apart. But for everyone and everything that doesn't
look at the page, they're completely different:
- Screen readers announce "navigation" or "main content" and let a
user jump directly to them. In a sea of
<div>s there's nothing to jump to. - Search engines weigh content in
<main>and<article>above repeated site chrome. - Browsers give semantic elements free behavior:
<button>is focusable and works with Enter and Space,<details>expands on click. - You can read your own code six months later.
The rule: choose the element for its meaning first, and style it afterwards.
2. The Page Landmarks
A handful of elements describe the major regions of a page. Assistive technology treats them as landmarks — signposts to jump between.
┌──────────────────────────────┐
│ <header> logo, title │
│ <nav> main links │
├──────────────────────────────┤
│ <main> │
│ <section> … │
│ <section> … │
├──────────────────────────────┤
│ <footer> contact, © notice │
└──────────────────────────────┘
| Element | Use it for |
|---|---|
<header> | Introductory content for the page (or a section): site name, logo, headline |
<nav> | A block of major navigation links |
<main> | The unique, central content. Exactly one per page |
<footer> | Closing info for the page (or a section): copyright, contact links |
Here's your profile page with landmarks added:
<body>
<header>
<h1>Dara Sok</h1>
<p>Junior web developer, Phnom Penh</p>
<nav aria-label="Main">
<ul>
<li><a href="index.html">Home</a></li>
<li><a href="about.html">About</a></li>
<li><a href="#contact">Contact</a></li>
</ul>
</nav>
</header>
<main>
<!-- page content -->
</main>
<footer>
<p>© 2026 Dara Sok</p>
</footer>
</body>
</html>
The navigation is a list of links inside <nav>, as mentioned in the
last chapter. aria-label="Main" gives the landmark a name, which
becomes important when a page has more than one <nav> (a main menu
and a footer menu, for example).
3. Sections, Articles, and Asides
Inside <main>, three elements group content:
| Element | Use it for | Test |
|---|---|---|
<section> | A themed group of content, with a heading | "Could this have its own heading in an outline?" |
<article> | A self-contained piece that makes sense on its own | "Would it still make sense in an RSS feed or when shared by itself?" |
<aside> | Related but tangential content: a sidebar, a note | "Can it be removed without hurting the main flow?" |
<main>
<section id="about">
<h2>About me</h2>
<p>…</p>
</section>
<section id="projects">
<h2>Projects</h2>
<article>
<h3>Recipe finder</h3>
<p>A small site for searching Cambodian recipes.</p>
</article>
<article>
<h3>Study timer</h3>
<p>A Pomodoro timer in plain JavaScript.</p>
</article>
</section>
</main>
Each project is an <article> because it stands alone. Each themed
group is a <section>, led by a heading. A <section> without a
heading is usually a sign you meant <div>.
Two more worth knowing: <figure> with <figcaption> wraps an image
and its caption, and <details> with <summary> makes a native
click-to-expand box with no JavaScript.
4. div and span: The Generic Elements
Sometimes there's no element that matches, and you only need a hook for styling or grouping. For that there are two meaningless ones:
<div>is a generic block container.<span>is a generic inline container.
<div class="card">
<h3>Study timer</h3>
<p>Built with <span class="tech">JavaScript</span>.</p>
</div>
They're not bad — layout often needs them. The mistake is using them
when a meaningful element exists. Before writing <div>, ask: is
this a header, a navigation, a list, a button, a section? If so, use
that. Use <div> as a last resort.
5. Why Accessibility Matters
Accessibility (often shortened to a11y) means building so that everyone can use your page, including people who:
- are blind or have low vision and use a screen reader or magnifier;
- can't use a mouse and rely on a keyboard or switch device;
- are deaf or hard of hearing and need captions;
- are colorblind or have low contrast sensitivity;
- have a temporary limit — a broken arm, bright sunlight on a phone screen, a slow connection.
That is a lot of people, and you will almost certainly be one of them at some point. It also helps search engines and, in many countries, it's a legal requirement for public sites. The good news: most of it is free if you use semantic HTML correctly. This series builds in accessibility as you go instead of treating it as an extra.
6. Using the Keyboard
Try this on your own page: put your mouse aside and press Tab.
Focus moves from one interactive element (links, buttons, form
fields) to the next, showing an outline around the current one. Enter
activates a link, and Space or Enter activates a button. Shift+Tab
goes backward.
What you should notice:
- You can reach every link in a sensible order, matching the order in your HTML.
- You always see where focus is. Never remove the focus outline with
outline: noneunless you replace it with something just as visible. - A
<div>with a click handler is not reachable. A real<a>or<button>is, automatically. That's the free behavior semantic elements give you.
A skip link helps keyboard users avoid tabbing through the whole
menu on every page. It's the first element in <body>:
<a href="#main">Skip to main content</a>
…
<main id="main">
It's often hidden until focused; chapter 7 shows how to style it.
7. Accessibility Checklist
Keep this list handy for every page you build:
| Check | Why |
|---|---|
<html lang="…"> is set | Right language and pronunciation |
One <h1>, headings in order | Navigable outline |
Landmarks: header, nav, main, footer | Jump between regions |
Every <img> has appropriate alt | Content for people who can't see it |
| Link text makes sense alone | Browsing a list of links |
Everything works with Tab and Enter | Keyboard users |
| Visible focus outline | Seeing where you are |
| Enough color contrast | Chapter 8 covers the numbers |
| Form fields have labels | Chapter 5 |
| Don't convey meaning by color alone | Colorblind users |
8. Restructure Your Page
Apply this to your project. Open index.html and:
- Wrap the title and menu in
<header>, with a<nav>containing a<ul>of links. - Wrap the content in
<main>, with one<section>per topic (About, Skills, Projects), each starting with an<h2>. - Turn each project into an
<article>with an<h3>. - Add a
<footer>with the copyright and an email link. - Add a skip link as the first element in
<body>. - Give the contact section
id="contact"so the nav link works.
Do the same for about.html, with the same header and footer.
9. Try It Yourself
- Tab through the page. Use only the keyboard. Does the order make sense? Is the focus always visible?
- Run Lighthouse. In Chrome DevTools open the Lighthouse panel, tick Accessibility, and run it. Read any warning it gives you.
- Listen to the page. Turn on a screen reader — VoiceOver on
macOS (
Cmd+F5), Narrator on Windows (Ctrl+Win+Enter), or NVDA (free). Navigate by headings and landmarks. Is your page understandable without seeing it? - Compare. Open a news site and inspect it. How many
<div>versus semantic elements does it use? Is there a<main>? - Validate and commit. Run the W3C validator once more. It checks
that you used
<main>once and nested things correctly.
Next, we'll add the interactive parts of HTML: forms for collecting input, and tables for showing data.
Buy Me a Coffee
Found this tutorial helpful? Consider buying me a coffee to support more free content!