DataLens

Semantic HTML (header, nav, main, footer)

Structure whole pages with landmark elements such as header, nav, main, article, section, aside and footer, so browsers, screen readers and teammates understand the layout.

Level: Foundations · 7 min read

Practise this module

The questions for this lesson run in your browser and check your answer straight away.

The idea

For years, web pages were built from <div>s: generic boxes with names like <div class="header">. They work, but the name is only for humans; the browser has no idea which box is the navigation and which is the main content. Semantic elements say what each part of the page is, and that unlocks real benefits:

The page landmarks

Almost every site has the same big pieces: a header with the logo and navigation at the top, the main content in the middle, and a footer at the bottom. HTML has an element for each of these, so the browser (and screen readers, and search engines) know exactly which part is which. Here's Toko Kita's page laid out with them:

<header>
  <a href="/">Toko Kita</a>
  <nav aria-label="Main">
    <ul>
      <li><a href="/coffee">Coffee</a></li>
      <li><a href="/equipment">Equipment</a></li>
      <li><a href="/about">About</a></li>
    </ul>
  </nav>
</header>

<main>
  <h1>Freshly roasted Indonesian coffee</h1>
  <p>Beans from Aceh to Papua, roasted every Monday in Bandung.</p>
</main>

<footer>
  <p>&copy; 2024 Toko Kita · <a href="mailto:[email protected]">[email protected]</a></p>
</footer>
ElementWhat it is
<header>Introductory content: logo, site name, main navigation
<nav>A block of major navigation links
<main>The page's main content. Exactly one per page
<footer>Closing content: copyright, contact, legal links

&copy; is an HTML entity, a code for a character: ©. Others you'll see are &amp; (&), &lt; (<) and &nbsp; (a space that never breaks a line).

Inside main: article, section, aside

The main area can be broken down further. Toko Kita has a coffee journal, a small blog. Each post stands on its own, has sections with their own headings, and the page has a box of related links on the side. Each of those has its own element:

<main>
  <h1>Coffee journal</h1>

  <article>
    <h2>Why we roast on Mondays</h2>
    <p>Published <time datetime="2024-10-07">7 October 2024</time></p>
    <p>Coffee tastes best a few days after roasting...</p>

    <section>
      <h3>The resting period</h3>
      <p>Freshly roasted beans release carbon dioxide for several days...</p>
    </section>
    <section>
      <h3>Shipping schedule</h3>
      <p>Monday roasts ship on Wednesday, arriving at their best...</p>
    </section>
  </article>

  <aside>
    <h2>Related</h2>
    <ul><li><a href="/journal/grind-size">Choosing a grind size</a></li></ul>
  </aside>
</main>

A useful test: if it could be shared or syndicated on its own, it's an article. If it's a chapter of something, it's a section. If it has no meaning of its own and just groups things for styling, it's a <div>.

<div> and <span> still have a place

Semantic elements don't replace <div> (a generic block) and <span> (a generic inline piece of text). Use them when no element describes the meaning, typically as hooks for CSS:

<article class="product-card">
  <h3>Arabica Gayo</h3>
  <div class="price-row">
    <span class="price">Rp 95.000</span>
    <span class="unit">/ 250 g</span>
  </div>
</article>

The rule: reach for a semantic element first, and fall back to <div>/<span> only when nothing fits.

Key idea

Build the page from landmarks (header, nav, main, footer) and give the main content meaningful parts (article, section, aside, time). Use div and span only when no element describes the meaning.

Headings give the outline

Every <section> and <article> should start with a heading, and heading levels should follow the structure: an <h1> for the page, <h2> for its main parts, <h3> inside those. Screen reader users navigate by headings more than by anything else, so the outline is the page's table of contents.

Why this matters for clean code

Semantic HTML is self-documenting code. Compare reading <div class="wrapper"><div class="top"><div class="links"> with <header><nav>: the second needs no comment. It also means fewer classes and less CSS to target the main areas, and accessibility that comes built in rather than bolted on.

Recap

Practise this module

The questions for this lesson run in your browser and check your answer straight away.

Next: Forms and inputs →