📝 Html Css

Semantic HTML5 Tags

P
Author
Pyland
📅
Published
30.06.2026
⏱️
Reading time
2 min
👁️
Views
82
🌿
Level
Medium

Semantic tags describe the meaning of content, not just its appearance. A browser won’t visually distinguish <div> from <article> — both are block-level. But a search engine, a screen reader, and the next developer who opens your code will instantly understand the page structure.

What semantics means in HTML

Compare two versions of the same markup:

<!-- No semantics — everything is a div -->
<div class="header">
  <div class="nav">...</div>
</div>
<div class="main">
  <div class="post">...</div>
  <div class="sidebar">...</div>
</div>
<div class="footer">...</div>

<!-- With semantics -->
<header>
  <nav>...</nav>
</header>
<main>
  <article>...</article>
  <aside>...</aside>
</main>
<footer>...</footer>

The second version communicates structure through the tags themselves, not through class names.

The core semantic tags

<header>

The introductory block of a page or section. Typically contains the logo, site title, and primary navigation.

<header>
  <a href="/" class="logo">DevBlog</a>
  <nav>
    <ul>
      <li><a href="/posts/">Articles</a></li>
      <li><a href="/about/">About</a></li>
    </ul>
  </nav>
</header>

<header> can appear inside <article> — then it’s the header of that specific article, not the whole site.

<nav>

The block of primary navigation. Not every group of links is a <nav> — only those that provide navigation around the site or page.

<nav aria-label="Main menu">
  <ul>
    <li><a href="/">Home</a></li>
    <li><a href="/posts/">Articles</a></li>
    <li><a href="/tags/">Tags</a></li>
  </ul>
</nav>

<main>

The main, unique content of the page. There should be only one <main> on a page. The header, footer, and sidebar don’t belong inside <main>.

<main>
  <!-- Everything unique to this page -->
</main>

<article>

A self-contained, independent piece of content: a blog post, an article, a product card, a comment. It should make sense if pulled out of context.

<article>
  <header>
    <h2><a href="/posts/asyncio/">The Complete asyncio Guide</a></h2>
    <time datetime="2025-03-15">March 15, 2025</time>
  </header>
  <p>We explore the event loop, coroutines, and practical patterns...</p>
  <footer>
    <a href="/posts/asyncio/">Read more</a>
  </footer>
</article>

<section>

A thematic section of content. Unlike <article>, it’s not self-contained — it’s part of a larger whole.

<section id="recent-posts">
  <h2>Recent Articles</h2>
  <!-- post cards -->
</section>

<section id="popular-tags">
  <h2>Popular Tags</h2>
  <!-- tag cloud -->
</section>

Each <section> should ideally start with a heading.

<aside>

Content tangentially related to the main content: sidebar, ad block, “Related articles” links, pull quotes.

<aside>
  <h3>Related articles</h3>
  <ul>
    <li><a href="/posts/generators/">Python Generators</a></li>
    <li><a href="/posts/contextmanager/">Context Managers</a></li>
  </ul>
</aside>

<footer>

The footer of a page or section: copyright, links, contact information.

<footer>
  <p>© 2025 DevBlog. Built with Python.</p>
  <nav aria-label="Footer links">
    <a href="/privacy/">Privacy</a>
    <a href="/rss.xml">RSS</a>
  </nav>
</footer>

<time>

A machine-readable date and time. The datetime attribute holds the standardised format:

<time datetime="2025-03-15">March 15, 2025</time>
<time datetime="2025-03-15T10:30:00+00:00">March 15 at 10:30</time>

Why this matters

Reason Explanation
SEO Google better understands content structure
Accessibility Screen readers present a list of landmarks (nav, main, aside) to users
Code readability Structure is clear without inspecting class names
Performance None — semantics don’t affect speed

Full example: DevBlog page

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <title>DevBlog — a Python developer's notes</title>
</head>
<body>

  <header>
    <a href="/" class="logo">DevBlog</a>
    <nav aria-label="Main menu">
      <ul>
        <li><a href="/posts/">Articles</a></li>
        <li><a href="/about/">About</a></li>
      </ul>
    </nav>
  </header>

  <main>
    <section id="recent-posts">
      <h1>Recent Articles</h1>

      <article>
        <header>
          <h2><a href="/posts/asyncio/">The asyncio Guide</a></h2>
          <time datetime="2025-03-15">March 15, 2025</time>
        </header>
        <p>Event loop, coroutines, and practical patterns.</p>
      </article>

      <article>
        <header>
          <h2><a href="/posts/pydantic-v2/">Pydantic v2: what's new</a></h2>
          <time datetime="2025-02-28">February 28, 2025</time>
        </header>
        <p>Key changes in Pydantic v2 explained.</p>
      </article>
    </section>

    <aside>
      <h2>Tags</h2>
      <ul>
        <li><a href="/tags/python/">Python</a></li>
        <li><a href="/tags/fastapi/">FastAPI</a></li>
      </ul>
    </aside>
  </main>

  <footer>
    <p>© 2025 DevBlog</p>
  </footer>

</body>
</html>

Use <div> only when no semantic tag fits. If you’re reaching for <div>, pause and ask: “What is this, semantically?” There’s usually an appropriate tag available.

Your reaction to the article

💬 Comments (0)

🔐 Sign in to leave a comment
🚪 Login
💭

No comments yet

Be the first to share your opinion about this article!

🔗 Similar

Similar articles

Continue learning with these materials

📝

AI Agents: ReAct Loop and Autonomous Actions

A chatbot answers questions. An agent takes action: it calls tools, retrieves real data, and...

📅 30.06.2026 👁️ 102
📝

RAG: Chatting with Documents via Vector Search

RAG (Retrieval-Augmented Generation) is a pattern for working with your own documents. Instead of fine-tuning...

📅 30.06.2026 👁️ 94
📝

Pod: The Smallest Unit in Kubernetes

In Docker you run a container. In Kubernetes the smallest unit is a Pod. It...

📅 30.06.2026 👁️ 91

Did you like the article?

Subscribe to our updates and receive new articles first. Grow with PyLand!