Hvis du har brugt <div> til alt — side-wrapper, navigation, artikelcontainer, sidebjælke — er du ikke alene. Det var standardtrækket i årevis. Men HTML har haft ordentlige semantiske elementer siden HTML5, og at bruge dem gør din kode lettere at læse, bedre for SEO og genuint mere tilgængelig. Lad os grave ned i de elementer, der faktisk betyder noget.
Ordet "semantisk" betyder blot, at elementet bærer mening ud over dets visuelle præsentation. En <div> betyder ingenting — det er et generisk blok-element. En <nav> fortæller browseren, søgemaskiner og hjælpeteknologier: "dette indeholder navigationslinks." Denne kontekst koster intet at tilføje og betaler sig på flere måder.
Hvorfor Semantik Betyder Noget
Tre virkelige fordele, ikke teoretiske:
- SEO. Søgemaskiner bruger dokumentstruktur til at forstå indholdshierarkiet. Et
<main>-element signalerer det primære indhold. En<article>inde i det signalerer et selvstændigt stykke. Google bruger disse signaler, når sider rangeres. - Tilgængelighed. Skærmlæsere eksponerer landmærkeregioner for brugere. Med
<nav>,<main>og<aside>på plads kan tastaturbrugere springe direkte til den sektion, de ønsker — uden at tabbe igennem hvert link på siden. - Vedligeholdbarhed. En ny udvikler, der læser din skabelon, forstår øjeblikkeligt sidestrukturen.
<header>/<main>/<footer>er selvdokumenterende på en måde, som<div class="top">/<div class="content">/<div class="bottom">ikke er.
De Grundlæggende Layoutelementer
Disse fem elementer håndterer det ydre skelet på de fleste sider. Brug dem på hver side, og du har allerede vundet halvdelen af den semantiske kamp:
<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>© 2026 MyBlog. All rights reserved.</p>
</footer>
</body><header>. Introduktionsindhold til siden eller en sektion. Indeholder normalt logoet, sidetitlen og primær navigation. Du kan også bruge det inden i<article>til en artikels eget overskriftsblok.<nav>. Et sæt navigationslinks. Ikke alle grupper af links behøver en<nav>— brug den til større navigationsblokke som sitenav eller sideinddeling.<main>. Det dominerende indhold på siden. Der bør kun være én<main>pr. side, og den bør ikke indeholde noget, der gentages på tværs af sider (header, nav, footer).<aside>. Indhold, der er løst relateret til hovedindholdet. Sidebjælker, udtrukne citater, relaterede artikler. Skærmlæsere eksponerer dette som et supplerende landmærke.<footer>. Sidefod til siden eller en sektion. Kan indeholde copyright-info, sekundær navigation, kontaktlinks eller en kort forfatternote.
<header> og <footer> er ikke begrænset til sideniveau. Hver <article> eller <section> kan have sin egen <header> og <footer>. Dette er særlig nyttigt til blogindlægs bylines og metadata på artikelniveau.article vs section — Hvornår Man Bruger Hvad
Dette er det, der forvirrer folk mest. Den tommelfingerregel, der faktisk virker: hvis indholdet ville give mening, hvis du syndikerede det alene (f.eks. udgav det som et RSS-indlæg eller delte det på et andet website), er det en <article>. Hvis det kun giver mening som del af en større helhed, er det en <section>.
<!-- 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 altid have en overskrift (<h2> til <h6>). Hvis din sektion ikke har en overskrift, er det normalt et tegn på, at du bør bruge en <div> i stedet. WHATWG-specifikationen er klar: <section> er til tematiske grupperinger, ikke vilkårlige layoutinddelinger.
figure, figcaption, time og address
Fire elementer, som udviklere ofte overser, men regelmæssigt har brug for:
<!-- 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 selvstændigt indhold, der refereres fra det primære flow — billeder, kodelistninger, diagrammer, videoer. Det afgørende: det kan flyttes til et tillæg uden at forstyrre læseflowet.<figcaption>. Billedteksten til en<figure>. Skal være det første eller sidste barn af<figure>. Giver en semantisk sammenhæng mellem billedteksten og indholdet, som<p>under et billede ikke gør.<time>. Menneskeligt læsbare datoer med et maskinlæsbartdatetime-attribut. Værdiendatetimebruger ISO 8601-format. Søgemaskiner bruger dette til event-markup og friskhedssignaler.<address>. Kontaktoplysninger til den nærmeste<article>-forfader (eller hele<body>). Ikke et generelt adresseelement — det er specifikt til kontaktoplysninger for indholdsforfatteren eller siteejeren.
Antipattern: Divitis
"Divitis" er, hvad der sker, når hvert element i dit HTML er en <div>. Her er et virkeligt før/efter, der viser problemet:
<!-- 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 version er faktisk kortere, kræver færre CSS-klassenavne og giver browsere og hjælpemidler alt, hvad de har brug for til at forstå sidestrukturen. Du kan stadig style alt præcist det samme med CSS — semantiske elementer pålægger ingen visuelle begrænsninger.
ARIA-roller — En Sidste Udvej, Ikke Et Første Træk
ARIA-roller lader dig tilføje semantisk mening til elementer, der ikke har det natively. Problemet er, at udviklere ofte griber til ARIA, når et semantisk HTML-element ville gøre jobbet bedre. Den første regel for ARIA: brug ikke ARIA, hvis du kan bruge native 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>Brug ARIA til interaktive widgets, som native HTML ikke dækker — fane-paneler, kombinationsbokse, trævisninger, datovælgere. For strukturelle landmærker som navigation, overskrifter og hovedindhold, støt dig altid til native elementer.
En Komplet Blogindlægssidesstruktur
Sådan ser en fuldt semantisk blogindlægsside ud. Dette er det mønster, der bruges på sider, der scorer godt i tilgængelhedsaudits uden ekstra indsats:
<!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>© 2026 TechBlog</small></p>
</footer>
</body>
</html>Bemærk den dobbelte brug af <header> og <footer> — én gang på sideniveau, én gang inden i <article>. Det er bevidst og korrekt. Bemærk også to <nav>-elementer med distinkte aria-label-værdier — dette forhindrer skærmlæsere i at liste to identiske "navigation"-regioner.
Hurtig Reference: Nyttige Værktøjer
Hvis du arbejder med HTML og ønsker at rydde op i eller validere din kode, vil HTML-formatering pynte og rydde op i din kode, og HTML-validatoren fanger strukturfejl som unclosed tags og manglende påkrævede attributter. For en dybere tilgængelhedsaudit har web.dev/accessibility fremragende diagnostik og forklaringer.
Opsummering
Semantisk HTML handler ikke om at følge regler for reglernes skyld — det handler om at skrive kode, der kommunikerer tydeligt til browsere, søgemaskiner, hjælpemidler og den næste udvikler, der læser din skabelon. Kernelementerne er enkle: <header>, <nav>, <main>, <article>, <section>, <aside> og <footer> dækker det overvejende flertal af virkelige sidestrukturer. Tilføj <figure>, <time> og <address> der, hvor de passer, grib til ARIA kun, når native HTML ikke er tilstrækkeligt, og du vil have kode, der er genuint en fornøjelse at arbejde med.