What Is Semantic HTML and Why Does It Matter?

March 7, 20266 min read

Early in my career I wrote a lot of <div> soup. Everything was a div. The header was a div. The nav was a div. The sidebar was a div with a class called sidebar-right-wrapper because apparently I needed two words to describe something that could have just been an <aside>.

It worked. Browsers are incredibly forgiving. But a senior dev on one of my first real projects pulled up my markup in a code review and said something that stuck with me: "Would a screen reader have any idea what's going on here?"

I didn't have a good answer. That's when I actually learned semantic HTML — not the definition, but why it matters in practice.

Why it's more than just "best practice"

When people say semantic HTML is a best practice, it sounds like one of those things you're supposed to do but nobody actually enforces. In reality there are three concrete reasons it affects real users and real outcomes.

Accessibility. Screen readers navigate by semantic landmarks. A <nav> element lets a blind user jump straight to navigation. A proper heading hierarchy lets them scan the document outline the same way a sighted user skims visually. Without those landmarks, the page is just one long wall of text read top to bottom.

The WebAIM Million report audits the top million websites every year. Every year, over 95% of home pages have detectable accessibility failures, and missing or incorrect semantic structure is always near the top. That's not a niche edge case — that's most of the web failing a basic test.

SEO. I'm always cautious about SEO claims because a lot of them are snake oil. This one isn't. Search crawlers parse your HTML to understand what a page is about. A <main> element tells Google where the actual content starts. <article> signals a standalone piece worth indexing independently. Heading tags communicate hierarchy and topic structure. None of this is magic, but it removes ambiguity for crawlers — and less ambiguity generally means better indexing.

Maintainability. Honestly, this is the one I care about most day to day. <header> is just faster to read than <div class="page-header-outer-wrapper">. When I open a codebase I haven't touched in a year, semantic structure tells me what's going on without me having to trace CSS class names back to some stylesheet. Future-me always appreciates past-me using the right tags.

The tags I actually use regularly

I'm not going to list every HTML5 semantic element — MDN does that better than I ever could. These are the ones that come up in almost every project.

<header>

Not just for the top of the page. A <header> inside an <article> is completely valid — it's the introductory part of that article, not the site header. I use it for both.

<header>
  <nav>...</nav>
  <h1>Dudych Blog</h1>
</header>

The mistake I see most often: people treat <header> as a singleton, like there can only be one per page. There can be multiple. Each semantic section can have its own.

<main>

One per page. Just one. It wraps the primary content — the stuff that's unique to this page and not repeated elsewhere. Your site-wide nav doesn't go in here. Your newsletter form that appears on every page doesn't go in here.

<main>
  <article>
    <!-- the actual post -->
  </article>
</main>

This is also useful for accessibility — screen readers have a "jump to main content" shortcut that relies on this element existing.

<article> vs <section> — the one that trips everyone up

These two cause more confusion than anything else. The distinction I use:

Can you lift this content out, drop it on a completely different site, and have it still make sense? If yes, it's an <article>. Blog posts, news articles, product cards, comments — all articles.

If no — if it's a thematic chunk of this page that doesn't stand on its own — it's a <section>.

If you can't even give it a meaningful name, it's a <div>.

Question Tag
Makes sense on another site entirely? <article>
Named section that belongs to this page? <section>
Just a layout container with no semantic meaning? <div>
<!-- A blog post listing -->
<article>
  <h2>What Is Semantic HTML?</h2>
  <p><time datetime="2026-03-07">March 7, 2026</time></p>
  <p>Content...</p>
</article>
 
<!-- A section within a longer article -->
<section>
  <h2>Why It Matters</h2>
  <p>...</p>
</section>

<aside>

Tangentially related content. Sidebars, pull quotes, author bios, related posts. The key word is tangentially — if the content is important to understanding the main article, it probably shouldn't be an <aside>.

<nav>

Navigation links. Not all link groups — just the ones that constitute actual navigation. The main menu, yes. Breadcrumbs, yes. The three links in the footer (home, privacy policy, copyright)? Probably not worth wrapping in <nav>.

If you have multiple <nav> elements on a page, add aria-label to distinguish them:

<nav aria-label="Main navigation">...</nav>
<nav aria-label="Post pagination">...</nav>

<time> — the underrated one

Nobody talks about this tag enough. Every date on your site should be in a <time> element:

<time datetime="2026-03-07T08:00:00Z">March 7, 2026</time>

The datetime attribute gives machines an unambiguous timestamp. The text content stays human-readable in whatever format you want. Search engines use this for rich results. Screen readers use it to announce dates correctly. Takes five seconds to add. Worth it every time.

What a properly structured page looks like

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>What Is Semantic HTML? | Dudych Blog</title>
  </head>
  <body>
 
    <header>
      <nav aria-label="Main navigation">
        <a href="/">Home</a>
        <a href="/blog">Blog</a>
        <a href="/about">About</a>
      </nav>
    </header>
 
    <main>
      <article>
 
        <header>
          <h1>What Is Semantic HTML and Why Does It Matter?</h1>
          <p>
            By Marian Dudych ·
            <time datetime="2026-03-07">March 7, 2026</time>
          </p>
        </header>
 
        <section>
          <h2>Why It Matters</h2>
          <p>...</p>
        </section>
 
        <section>
          <h2>The Tags You Should Know</h2>
          <p>...</p>
        </section>
 
        <footer>
          <p>Filed under: HTML, Accessibility</p>
        </footer>
 
      </article>
 
      <aside>
        <h2>Related Posts</h2>
        <ul>...</ul>
      </aside>
    </main>
 
    <footer>
      <p>© 2026 Dudych Blog</p>
    </footer>
 
  </body>
</html>

Notice the <header> and <footer> nested inside <article>. Completely valid. The article header contains the title and byline. The article footer contains tags and metadata. It reads exactly like what it is.

The thing I see wrong most often

Using semantic tags for their visual side effects rather than their meaning.

<blockquote> to indent arbitrary text. <ul> to shift content left. <h3> because "that's about the right font size." I've done all of these. They're wrong.

The browser's default rendering of semantic elements is a side effect, not the point. CSS handles visuals. HTML handles meaning. The moment you pick a tag based on how it looks in a browser without styles, you've introduced a bug — it's just a bug that doesn't throw an error.

A test I find useful: disable all CSS on the page. Does the document still communicate its structure clearly? Can you tell what's a heading, what's navigation, what's the main content? If yes, you're in good shape.

A checklist before I ship

I don't always run through this explicitly, but it's what I'm checking for:

  • One <main> per page, contains only page-specific content
  • Heading hierarchy is sequential — no jumping from <h1> to <h3>
  • Dates are in <time> elements with datetime attributes
  • Standalone content is in <article>, thematic sections in <section>
  • Multiple <nav> elements have aria-label attributes
  • No tag chosen for its visual appearance rather than its meaning

Worth learning properly

This is one of those fundamentals that has an outsized return on investment. A few hours spent actually understanding the element spec pays off every time you write markup — better accessibility, better SEO, cleaner code.

The MDN HTML elements reference is where I go when I'm not sure about a specific element. The HTML Living Standard is more exhaustive if you want the full picture.

Start with <main>, <article>, <section>, and <nav>. Get those right consistently and you're already ahead of most of the web.

Stay in the loop

Subscribe for new posts on web development, TypeScript, and tooling. No spam, ever.

No spam. Unsubscribe anytime.