Hvis du har brukt <div> til alt — side-wrapper, navigasjon, artikkelcontainer, sidefelt — er du ikke alene. Det var standardgrepet i årevis. Men HTML har hatt ordentlige semantiske elementer siden HTML5, og å bruke dem gjør koden lettere å lese, bedre for SEO og genuint mer tilgjengelig. La oss grave inn i elementene som faktisk betyr noe.

Ordet "semantisk" betyr bare at elementet bærer mening utover den visuelle presentasjonen. En <div> betyr ingenting — det er et generisk blokklement. En <nav> forteller nettleseren, søkemotorer og hjelpeteknologier: "dette inneholder navigasjonslenker." Den konteksten koster ingenting å legge til og lønner seg på flere måter.

Hvorfor Semantikk Betyr Noe

Tre virkelige fordeler, ikke teoretiske:

  • SEO. Søkemotorer bruker dokumentstruktur for å forstå innholdshierarkiet. Et <main>-element signaliserer det primære innholdet. En <article> inni det signaliserer en frittstående del. Google bruker disse signalene ved rangering av sider.
  • Tilgjengelighet. Skjermlesere eksponerer landemerkeregioner for brukere. Med <nav>, <main> og <aside> på plass kan tastaturbrukere hoppe direkte til seksjonen de vil ha — uten å tabbe gjennom hver lenke på siden.
  • Vedlikeholdbarhet. En ny utvikler som leser malen din forstår øyeblikkelig sidestrukturen. <header>/<main>/<footer> er selvdokumenterende på en måte som <div class="top">/<div class="content">/<div class="bottom"> ikke er.

De Grunnleggende Layoutelementene

Disse fem elementene håndterer det ytre skjelettet på de fleste sider. Bruk dem på hver side og du har allerede vunnet halvparten av den semantiske kampen:

html
<body>
  <header>
    <a href="/" class="logo">MyBlog</a>
    <nav>
      <ul>
        <li><a href="/articles">Articles</a></li>
        <li><a href="/about">About</a></li>
        <li><a href="/contact">Contact</a></li>
      </ul>
    </nav>
  </header>

  <main>
    <!-- Primary page content goes here -->
  </main>

  <aside>
    <!-- Sidebar: related links, ads, author bio -->
  </aside>

  <footer>
    <p>&copy; 2026 MyBlog. All rights reserved.</p>
  </footer>
</body>
  • <header>. Introduksjonsinnhold for siden eller en seksjon. Inneholder vanligvis logoen, nettstedtittelen og primær navigasjon. Du kan også bruke den inni <article> for en artikkelens eget overskriftsblokk.
  • <nav>. Et sett med navigasjonslenker. Ikke alle grupper av lenker trenger en <nav> — bruk den til store navigasjonsblokker som nettstedsnav eller paginering.
  • <main>. Det dominerende innholdet på siden. Det bør bare være én <main> per side, og den bør ikke inneholde noe som gjentas på tvers av sider (header, nav, footer).
  • <aside>. Innhold som er løst relatert til hovedinnholdet. Sidefelt, utdrag, relaterte artikler. Skjermlesere eksponerer dette som et supplerende landemerke.
  • <footer>. Bunntekst for siden eller en seksjon. Kan inneholde opphavsrettsinformasjon, sekundær navigasjon, kontaktlenker eller en kort forfatternote.
Vanlig feil: <header> og <footer> er ikke begrenset til sidenivå. Hver <article> eller <section> kan ha sin egen <header> og <footer>. Dette er særlig nyttig for blogginnleggs bylines og metadata på artikkelnivå.

article vs section — Når Man Bruker Hvert

Dette er det som forvirrer folk mest. Tommelfingerregelen som faktisk fungerer: hvis innholdet ville gi mening hvis du syndikerte det på egen hånd (f.eks. publiserte det som et RSS-innlegg eller delte det på et annet nettsted), er det en <article>. Hvis det bare gir mening som del av en større helhet, er det en <section>.

html
<!-- article: self-contained, could stand alone -->
<article>
  <header>
    <h2>Understanding HTTP/2 Push</h2>
    <p>By Alice Chen — <time datetime="2026-03-15">March 15, 2026</time></p>
  </header>
  <p>HTTP/2 Server Push lets the server send resources...</p>
  <footer>
    <p>Tagged: <a href="/tags/http">HTTP</a>, <a href="/tags/performance">Performance</a></p>
  </footer>
</article>

<!-- section: thematic grouping within a page -->
<section>
  <h2>Related Articles</h2>
  <ul>
    <li><a href="/http3-quic">HTTP/3 and QUIC Explained</a></li>
    <li><a href="/cdn-strategy">CDN Strategy for Global Apps</a></li>
  </ul>
</section>

<section> bør alltid ha en overskrift (<h2> til <h6>). Hvis seksjonen din ikke har en overskrift, er det vanligvis et tegn på at du bør bruke en <div> i stedet. WHATWG-spesifikasjonen er klar: <section> er for tematiske grupperinger, ikke vilkårlige layoutinndelinger.

figure, figcaption, time og address

Fire elementer som utviklere ofte overser, men jevnlig trenger:

html
<!-- figure + figcaption: images, code blocks, diagrams, charts -->
<figure>
  <img src="/images/latency-chart.png" alt="P99 latency over 24 hours showing a spike at 14:30">
  <figcaption>Figure 1: API latency during the Tuesday incident (UTC).</figcaption>
</figure>

<!-- A code block as a figure (totally valid) -->
<figure>
  <pre><code>const result = await db.query('SELECT * FROM users WHERE active = true');</code></pre>
  <figcaption>Listing 1: Basic active user query.</figcaption>
</figure>

<!-- time: machine-readable dates and times -->
<p>Published <time datetime="2026-04-16T09:00:00Z">April 16, 2026</time></p>
<p>Sale ends in <time datetime="PT2H30M">2 hours 30 minutes</time></p>

<!-- address: contact info for nearest article or body ancestor -->
<address>
  Written by <a href="mailto:[email protected]">Alice Chen</a>.<br>
  123 Dev Street, San Francisco, CA.
</address>
  • <figure>. Alt frittstående innhold som det refereres til fra hovedflyten — bilder, kodelistinger, diagrammer, videoer. Det avgjørende: det kan flyttes til et tillegg uten å forstyrre leseflaten.
  • <figcaption>. Bildeteksten for en <figure>. Må være det første eller siste barnet av <figure>. Gir en semantisk sammenheng mellom bildeteksten og innholdet som <p> under et bilde ikke gir.
  • <time>. Menneskelig lesbare datoer med et maskinlesbart datetime-attributt. Verdien datetime bruker ISO 8601-format. Søkemotorer bruker dette for arrangementmarkering og ferskhetssignaler.
  • <address>. Kontaktinformasjon for nærmeste <article>-forgjenger (eller hele <body>). Ikke et generelt adresseelement — det er spesifikt for kontaktinformasjon for innholdsforfatteren eller nettstedseieren.

Antimønstre: Divitis

"Divitis" er det som skjer når hvert element i HTML-en din er en <div>. Her er et virkelig før/etter som viser problemet:

html
<!-- Before: divitis -->
<div class="page">
  <div class="header">
    <div class="brand">TechBlog</div>
    <div class="nav">
      <div class="nav-item"><a href="/posts">Posts</a></div>
    </div>
  </div>
  <div class="post">
    <div class="post-title">Why TypeScript Is Worth It</div>
    <div class="post-meta">By Bob — Jan 2026</div>
    <div class="post-body">TypeScript adds static types to JavaScript...</div>
  </div>
</div>

<!-- After: semantic HTML -->
<body>
  <header>
    <span class="brand">TechBlog</span>
    <nav>
      <a href="/posts">Posts</a>
    </nav>
  </header>
  <main>
    <article>
      <header>
        <h1>Why TypeScript Is Worth It</h1>
        <p>By Bob — <time datetime="2026-01-10">January 10, 2026</time></p>
      </header>
      <p>TypeScript adds static types to JavaScript...</p>
    </article>
  </main>
</body>

Den semantiske versjonen er faktisk kortere, krever færre CSS-klassenavn og gir nettlesere og hjelpemidler alt de trenger for å forstå sidestrukturen. Du kan fortsatt style alt nøyaktig det samme med CSS — semantiske elementer påtvinger ingen visuelle begrensninger.

ARIA-roller — En Siste Utvei, Ikke Et Første Trekk

ARIA-roller lar deg legge til semantisk mening til elementer som ikke har det innebygd. Problemet er at utviklere ofte griper til ARIA når et semantisk HTML-element ville gjort jobben bedre. Den første regelen for ARIA: ikke bruk ARIA hvis du kan bruke native HTML.

html
<!-- Wrong: using ARIA where native HTML works -->
<div role="navigation">
  <a href="/home">Home</a>
</div>

<!-- Right: just use the semantic element -->
<nav>
  <a href="/home">Home</a>
</nav>

<!-- ARIA is appropriate here: custom widget with no HTML equivalent -->
<div
  role="tablist"
  aria-label="Code examples"
>
  <button role="tab" aria-selected="true" aria-controls="panel-js">JavaScript</button>
  <button role="tab" aria-selected="false" aria-controls="panel-py">Python</button>
</div>

Bruk ARIA for interaktive widgeter som native HTML ikke dekker — fanepaneler, kombinasjonsbokser, trevisninger, datovelgere. For strukturelle landemerker som navigasjon, overskrifter og hovedinnhold, støtt deg alltid til native elementer.

En Komplett Blogginnleggssidestruktur

Slik ser en fullt semantisk blogginnleggsside ut. Dette er mønsteret som brukes på nettsteder som scorer godt i tilgjengelighetskontroller uten ekstra innsats:

html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Why TypeScript Is Worth It — TechBlog</title>
</head>
<body>
  <header>
    <a href="/" class="logo">TechBlog</a>
    <nav aria-label="Site navigation">
      <ul>
        <li><a href="/posts">Posts</a></li>
        <li><a href="/topics">Topics</a></li>
        <li><a href="/about">About</a></li>
      </ul>
    </nav>
  </header>

  <main>
    <article>
      <header>
        <h1>Why TypeScript Is Worth It</h1>
        <address>
          By <a rel="author" href="/authors/bob">Bob Martinez</a>
        </address>
        <p>Published <time datetime="2026-01-10">January 10, 2026</time></p>
      </header>

      <section>
        <h2>The Setup Cost Is Real but Front-Loaded</h2>
        <p>TypeScript adds a compilation step and requires type annotations...</p>

        <figure>
          <pre><code>interface User {
  id: number;
  name: string;
  email: string;
}</code></pre>
          <figcaption>Listing 1: A typed User interface catches shape errors at compile time.</figcaption>
        </figure>
      </section>

      <section>
        <h2>Where TypeScript Pays Off</h2>
        <p>The ROI kicks in as team size and codebase complexity grows...</p>
      </section>

      <footer>
        <p>
          Tagged: <a href="/tags/typescript">TypeScript</a>,
          <a href="/tags/javascript">JavaScript</a>
        </p>
      </footer>
    </article>

    <aside aria-label="Related articles">
      <h2>You Might Also Like</h2>
      <ul>
        <li><a href="/ts-vs-js">TypeScript vs JavaScript — A Practical Comparison</a></li>
        <li><a href="/ts-generics">TypeScript Generics Explained</a></li>
      </ul>
    </aside>
  </main>

  <footer>
    <nav aria-label="Footer navigation">
      <a href="/privacy">Privacy</a>
      <a href="/terms">Terms</a>
    </nav>
    <p><small>&copy; 2026 TechBlog</small></p>
  </footer>
</body>
</html>

Legg merke til den doble bruken av <header> og <footer> — én gang på sidenivå, én gang inni <article>. Det er bevisst og korrekt. Legg også merke til to <nav>-elementer med distinkte aria-label-verdier — dette hindrer skjermlesere i å liste opp to identiske "navigasjon"-regioner.

Hurtigreferanse: Nyttige Verktøy

Hvis du arbeider med HTML og ønsker å rydde opp i eller validere koden din, vil HTML-formatering pynte og rydde opp i koden din, og HTML-validatoren fanger strukturfeil som uklukkede tagger og manglende påkrevde attributter. For en dypere tilgjengelighetskontroll har web.dev/accessibility fremragende diagnostikk og forklaringer.

Oppsummering

Semantisk HTML handler ikke om å følge regler for reglenes skyld — det handler om å skrive kode som kommuniserer tydelig til nettlesere, søkemotorer, hjelpemidler og den neste utvikleren som leser malen din. Kjerneelementene er enkle: <header>, <nav>, <main>, <article>, <section>, <aside> og <footer> dekker det overveldende flertallet av virkelige sidestrukturer. Legg til <figure>, <time> og <address> der de passer, grip til ARIA bare når native HTML ikke strekker til, og du vil ha kode som genuint er en fornøyelse å arbeide med.