Semantisches HTML · Grundlagen & Struktur
Struktur-Elemente: header, nav, main & footer
<header>, <nav>, <main> und <footer> teilen eine Seite in benannte Bereiche, die Screenreader als Sprungziele anbieten und Suchmaschinen als Rollen auswerten – ohne ein einziges role-Attribut. Ob ein Element tatsächlich zur Landmark wird, hängt allerdings davon ab, wo es steht: derselbe <header> ist im <body> ein Banner und innerhalb eines <article> nur ein generischer Container.
Das Wichtigste in Kürze
- Vier Elemente bilden das Grundgerüst:
<header>(einleitend),<nav>(wesentliche Navigation),<main>(zentraler Inhalt),<footer>(abschließend). - Aus ihnen entstehen automatisch die ARIA-Landmarks
banner,navigation,mainundcontentinfo. Zusätzlicherole-Attribute sind überflüssig. -
<header>und<footer>verlieren ihre Landmark-Rolle, sobald sie inarticle,aside,main,navodersectionliegen. Dann sind sie nurgeneric– so festgelegt in ARIA in HTML. -
Pro Dokument ist genau ein sichtbares
<main>erlaubt. Es ist das Sprungziel des Skip-Links. - Mehrere
<nav>-Bereiche brauchen je einaria-label, sonst meldet der Screenreader zweimal nur „Navigation“. - Für Suchformulare gibt es seit Oktober 2023 das eigene Element
<search>mit der Rollesearch– es ersetzt<form role="search">. - Ein
<section>wird nur dann zur Landmarkregion, wenn es einen zugänglichen Namen hat. Ohne Namen ist es ein<div>mit mehr Buchstaben. - WCAG-Bezug: 2.4.1 Blöcke umgehen (Stufe A) verlangt einen Mechanismus, um wiederkehrende Blöcke zu überspringen – Landmarks sind einer davon.
Das Grundgerüst
<body>
<a class="skip-link" href="#inhalt">Zum Inhalt springen</a>
<header>
<a href="/index.html">Logo</a>
<nav aria-label="Hauptnavigation">
<ul>
<li><a href="/semantisches-html.html">Semantisches HTML</a></li>
</ul>
</nav>
</header>
<main id="inhalt">
<h1>Seitentitel</h1>
<p>…</p>
</main>
<footer>
<p>© 2026 …</p>
</footer>
</body>
Diese Reihenfolge – einleitender Bereich, Hauptinhalt, abschließender Bereich – entspricht der Lesefolge und der Struktur, die assistive Technologien erwarten. Wenn ich ein neues Template beginne, steht dieses Gerüst als Erstes. Ich würd damit anfangen, bevor die erste Zeile CSS entsteht: Später umzubauen ist deutlich mühsamer, als es von Anfang an richtig hinzuschreiben.
Was ein Screenreader daraus baut
Screenreader bieten diese Bereiche als Liste an, aus der man direkt springt: in NVDA über die Elementliste, in VoiceOver über das Rotor-Menü, in JAWS mit der Taste R. Wer nur mit der Maus arbeitet, merkt davon nichts – für Tastatur- und Screenreader-Nutzung ist es der Unterschied zwischen „drei Sekunden zum Inhalt“ und „vierzig Tab-Sprünge durch das Menü“.
<header>
Der <header> enthält einleitende Inhalte: Logo, Seitentitel, oft die Hauptnavigation, manchmal ein Suchfeld. Wichtig ist eine Unterscheidung, die häufig untergeht: <header> ist nicht auf die Seite als Ganzes beschränkt. Auch ein <article> darf einen eigenen <header> für Überschrift und Metadaten haben.
<article>
<header>
<h2>Beitragstitel</h2>
<p>Veröffentlicht am <time datetime="2026-06-26">26. Juni 2026</time></p>
</header>
<p>…</p>
</article>
Nur der <header>, der nicht in article, aside, main, nav oder section liegt, wird zur Landmark banner. Ein <header> im <article> ist dagegen ein generischer Container – erwünscht, denn sonst hätte eine Übersichtsseite mit zwanzig Beiträgen einundzwanzig Banner in der Sprungliste.
<nav>
<nav> kennzeichnet einen Block mit wesentlichen Navigationslinks. Nicht jede Linksammlung braucht es – ein paar Links im Fließtext kommen ohne aus. Für die Hauptnavigation, eine Seitenleiste oder Breadcrumbs ist es genau richtig.
Hat eine Seite mehrere <nav>-Bereiche, müssen sie unterscheidbar sein:
<nav aria-label="Hauptnavigation">…</nav>
<nav aria-label="Brotkrümel">…</nav>
So liest ein Screenreader „Hauptnavigation“ bzw. „Brotkrümel“ vor, statt zweimal nur „Navigation“. Zwei Details, die dabei oft schiefgehen:
- Das Wort „Navigation“ nicht wiederholen. Die Rolle wird bereits angesagt.
aria-label="Hauptnavigation"ergibt „Hauptnavigation, Navigation“ – das ist noch erträglich.aria-label="Navigation Hauptmenü"ergibt „Navigation Hauptmenü, Navigation“. - Links gehören in eine Liste. Ein
<ul>innerhalb von<nav>vermittelt die Anzahl der Einträge („Liste, 6 Einträge“) – eine Information, die bei losen<a>-Elementen fehlt. Mehr dazu unter Listen richtig nutzen.
Bei mehrstufigen Menüs kommt Tastaturlogik hinzu, die HTML allein nicht liefert – das Muster steht unter Mega-Menüs.
<main>
<main> umschließt den zentralen, einzigartigen Inhalt der Seite. Weder die seitenweite Navigation noch wiederkehrende Footer-Inhalte gehören hinein. Zwei Regeln sind hier entscheidend:
- Es gibt genau ein sichtbares
<main>pro Dokument. Weitere Vorkommen sind nur erlaubt, wenn sie dashidden-Attribut tragen – etwa in einer App, die Ansichten vorlädt. - Die Vorfahren sind eng begrenzt: Der Standard erlaubt oberhalb von
<main>nurhtml,body,div, einformohne zugänglichen Namen und eigene Custom Elements. Ein<main>in<article>,<aside>,<section>,<header>,<footer>oder<nav>ist also nicht bloß unschön, sondern ungültig.
Es ist außerdem das natürliche Sprungziel für den Skip-Link:
<a class="skip-link" href="#inhalt">Zum Inhalt springen</a>
…
<main id="inhalt">…</main>
Ein Detail, das sich verändert hat: Jahrelang galt tabindex="-1" am Sprungziel als Pflicht, weil der Fokus sonst am Seitenanfang blieb und der nächste Tab-Druck wieder ins Menü führte. Browser lösen das inzwischen über den „sequential focus navigation starting point“ – Firefox seit 2013, Chrome seit 2016. Stand Juli 2026 ist das Attribut in gängigen Browser-Screenreader-Kombinationen nicht mehr nötig.
<!-- Reicht heute in der Regel aus -->
<main id="inhalt">…</main>
Zwei Ausnahmen sind dokumentiert: VoiceOver lässt den Fokus beim Betätigen mit Enter teils auf dem Link stehen, und tabindex="-1" am <main> kann auf iOS die Zurück-Funktion des Browsers stören. Wenn du das Attribut in bestehendem Code findest, lohnt eher ein Test als ein reflexartiges Entfernen.
<footer>
Der <footer> enthält abschließende Informationen zu seinem übergeordneten Bereich: Copyright, rechtliche Links, Kontaktangaben, manchmal eine sekundäre Navigation. Wie beim <header> gilt: Ein <footer> direkt im <body> ist die Landmark contentinfo; ein <footer> innerhalb eines <article> beschreibt nur diesen Beitrag – etwa Autorzeile und Schlagwörter.
<footer>
<nav aria-label="Rechtliche Hinweise">
<ul>
<li><a href="/impressum.html">Impressum</a></li>
<li><a href="/datenschutz.html">Datenschutz</a></li>
</ul>
</nav>
<p><small>© 2026 html-einfach.de</small></p>
</footer>
Die Regel, an der die meisten Landmarks scheitern
Ob ein Element zur Landmark wird, entscheidet nicht das Element allein, sondern seine Position im Baum. Diese Tabelle fasst die Zuordnung nach ARIA in HTML zusammen – Stand Juli 2026:
| Element | Rolle | Bedingung |
|---|---|---|
<header> |
banner |
nicht in article, aside, main, nav, section |
<footer> |
contentinfo |
dieselbe Bedingung |
<main> |
main |
immer |
<nav> |
navigation |
immer |
<aside> |
complementary |
immer |
<section> |
region |
nur mit zugänglichem Namen |
<search> |
search |
immer |
<form> |
form |
nur mit zugänglichem Namen |
<div>, <span> |
generic |
immer – siehe div vs. span |
Die letzten beiden Zeilen erklären ein Rätsel, über das viele stolpern: Ein <section> ohne aria-label oder aria-labelledby taucht in keiner Landmark-Liste auf. Wer sich also fragt, warum die sorgfältig gesetzten <section>-Elemente im Prüfwerkzeug nicht erscheinen – das ist kein Fehler, sondern die Spezifikation. Und es ist ein Argument dafür, <section> sparsam einzusetzen; welches Element wann passt, klärt article vs. section.
Das vergessene Element: <search>
Für Suchbereiche gibt es seit Oktober 2023 ein eigenes Element. Es ist in allen aktuellen Browsern verfügbar (Baseline „widely available“) und trägt die Rolle search:
<!-- Früher: role nachgerüstet -->
<form role="search" action="/suche.html">…</form>
<!-- Heute: eigenes Element, Rolle inklusive -->
<search>
<form action="/suche.html">
<label for="q">Suchbegriff</label>
<input type="search" id="q" name="q" />
<button type="submit">Suchen</button>
</form>
</search>
Zwei Hinweise dazu: <search> ist der Container für die Suchfunktion, nicht für die Trefferliste – die gehört in den normalen Seiteninhalt. Und mehrere <search>-Bereiche pro Seite sind zulässig, etwa eine globale Suche im Header und ein Filter über einer Tabelle. Dann gilt dieselbe Regel wie bei <nav>: benennen.
Randnotiz – auch Maschinen lesen die Rollen. Ob ein Bereich Navigation, Hauptinhalt oder Fußzeile ist, erschließt sich Web-Crawlern (Googlebot) und KI-Crawlern (GPTBot, ClaudeBot) aus dem Element. Für die Frage, welcher Teil einer Seite zitierfähig ist und welcher nur Beiwerk, ist ein sauberes
<main>das stärkste Signal, das HTML hergibt. Wie das mit Sichtbarkeit zusammenhängt, steht unter Semantik & SEO.
Ergänzend: aside, section, article
Die vier Grundelemente werden meist von drei weiteren begleitet:
-
<aside>für ergänzende Inhalte mit losem Bezug zum Hauptinhalt: Infokästen, weiterführende Links, Werbung. Wird zur Landmarkcomplementary. -
<section>für thematische Abschnitte mit eigener Überschrift – und, wenn eine Landmark daraus werden soll, mitaria-labelledbyauf diese Überschrift. -
<article>für in sich abgeschlossene Inhalte, die auch außerhalb der Seite Sinn ergeben: ein Beitrag, ein Kommentar, eine Produktkarte.
<section aria-labelledby="tests">
<h2 id="tests">Testverfahren</h2>
<p>…</p>
</section>
Das ist der Trick, mit dem aus <section> eine benannte Landmark wird, ohne den Namen doppelt zu pflegen: aria-labelledby zeigt auf die sichtbare Überschrift.
Kleinere Helfer: address und hgroup
Zwei Elemente runden das Bild ab, ohne eine eigene Seite zu brauchen:
-
<address>zeichnet Kontaktinformationen aus – die des Dokuments (oft im<footer>) oder die des nächsten<article>. Es ist nicht für beliebige postalische Adressen im Fließtext gedacht, sondern für „so erreichst du die Verantwortlichen“. Eine Lieferadresse in einer Bestellübersicht gehört also nicht hinein. -
<hgroup>bündelt eine Überschrift mit einem unmittelbar zugehörigen Zusatz. Der Inhalt ist festgelegt: genau eine Überschrifth1–h6, davor und danach beliebig viele<p>. So belegt ein Untertitel keine eigene Überschriftenebene und die Hierarchie bleibt sauber.
<hgroup>
<h1>Struktur-Elemente</h1>
<p>Das Grundgerüst jeder Seite in vier Elementen</p>
</hgroup>
Randnotiz – der Outline-Algorithmus ist weg. Lange hielt sich die Vorstellung,
<section>berechne Überschriftenebenen automatisch: eine<h1>in verschachtelten Sections werde zurh2,h3und so weiter. Kein Browser hat das jemals umgesetzt, und im HTML-Standard ist der Algorithmus inzwischen gestrichen. Stand Juli 2026 gilt: Die Outline ist einfach die Folge allerh1–h6in Dokumentreihenfolge, und die Ebene schreibst du selbst hin. Ein neues Attributheadingoffsetsoll das Verschieben von Ebenen künftig ermöglichen; es steckt jedoch in Firefox Nightly hinter einem Flag, Chromium prototypt, WebKit hat sich nicht geäußert. Für Produktivcode heißt das: noch nicht einsetzen.
Sichtbare Reihenfolge und Quelltext-Reihenfolge
Mit CSS Grid und Flexbox lassen sich Bereiche visuell fast beliebig umsortieren – order, grid-row, flex-direction: row-reverse. Tastatur und Screenreader folgen aber weiter dem Quelltext. Wer die Seitenleiste per CSS nach oben schiebt, sie im HTML aber hinter dem <main> stehen lässt, erzeugt eine Reihenfolge, die für sehende Nutzung anders aussieht als für Tastaturnutzung.
Genau das verbietet WCAG 1.3.2 Bedeutungstragende Reihenfolge (Stufe A). Die Faustregel: Die Quelltext-Reihenfolge muss für sich schlüssig sein. Wenn du das CSS abschaltest und die Seite noch in einer sinnvollen Folge lesbar ist, passt es.
So prüfst du dein Grundgerüst in drei Minuten
- CSS abschalten. In den Entwicklerwerkzeugen alle Stylesheets deaktivieren. Bleibt eine erkennbare Folge aus Kopfbereich, Überschriften, Inhalt und Fußbereich? Wenn alles zu einem grauen Block zerfällt, fehlt Semantik – das Muster beschreibt „Div-Soup“ vermeiden.
- Landmarks zählen. Eine Landmark-Erweiterung im Browser oder das Accessibility-Panel der Entwicklerwerkzeuge öffnen. Erwartet werden genau ein
banner, einmain, eincontentinfound pro Navigationsbereich ein benanntesnavigation. - Mit der Tastatur durchgehen. Seite neu laden, einmal Tab drücken. Erscheint der Skip-Link? Führt Enter in den Hauptinhalt, und geht es von dort weiter – nicht zurück an den Seitenanfang?
- Mit dem Screenreader die Sprungliste öffnen. In NVDA über die Elementliste, in VoiceOver über den Rotor. Sind die Bereiche unterscheidbar benannt? Anleitungen: Mit NVDA testen und Mit VoiceOver testen.
- Validieren. Der W3C-Validator findet ein zweites sichtbares
<main>, eine<hgroup>mit zwei Überschriften und falsch verschachtelte Bereiche zuverlässig.
Häufiger Fehler in der Praxis
Der Fehler, den ich am häufigsten sehe, ist nicht ein fehlendes <main> – das haben inzwischen die meisten Templates. Es ist die doppelte Landmark durch ein Framework. Ein Layout-Baustein bringt seinen eigenen <header> mit, das Seitentemplate setzt noch einen, und in der Sprungliste stehen plötzlich zwei Banner ohne Namen. Für Screenreader-Nutzung ist das schlimmer als gar keine Landmark, weil die Liste ihren Wert als Orientierung verliert.
Der zweite Klassiker: <nav> um jede Linksammlung. Eine Seite mit Hauptnavigation, Breadcrumb, Inhaltsverzeichnis, Fußnavigation, Sprachumschalter und „Weiterlesen“-Block liefert sechs Navigationsbereiche. Technisch korrekt, praktisch unbrauchbar – die Liste, die Orientierung geben soll, ist selbst zum Labyrinth geworden. Meine Grenze liegt bei drei <nav> pro Seite; alles Weitere ist eine Linkliste in einem <div> und verliert dadurch nichts.
Und drittens: aria-label am <main>. Das braucht es nicht. Es gibt nur eines, die Rolle ist eindeutig, ein Name stiftet keinen zusätzlichen Nutzen. Das gehört in dieselbe Kategorie wie role="navigation" am <nav> – siehe die erste Regel von ARIA.
Häufige Fehler
-
Mehrere sichtbare
<main>pro Seite. Erlaubt ist genau eines ohnehidden. -
<header>im<article>für eine Banner-Landmark halten. Dort ist esgeneric. -
Jede Linkliste zur
<nav>erklären.<nav>ist für wesentliche Navigation. -
Mehrere
<nav>nicht benennen. Ohnearia-labelheißen alle „Navigation“. -
<section>ohne Namen als Landmark erwarten. Ohne zugänglichen Name bleibt esgeneric. -
role="banner",role="main"oderrole="navigation"zusätzlich setzen. Doppelt hält hier nicht besser. -
Alles in
<section>verpacken. Ohne eigenes Thema und Überschrift ist<div>die bessere Wahl. -
<form role="search">statt des Elements<search>. -
aria-labelam<main>. Es gibt nur eines, die Rolle ist eindeutig.
Häufige Fragen
Muss jede Seite alle vier Elemente haben?
Nein, aber <main> sollte immer da sein – es ist das Sprungziel und das stärkste Signal für den eigentlichen Inhalt. <header> und <footer> sind praktisch immer sinnvoll, <nav> nur, wenn es wesentliche Navigation gibt. Eine reine Landingpage ohne Menü braucht kein <nav>.
Darf <nav> außerhalb des <header> stehen?
Ja. Die Hauptnavigation liegt oft im <header>, muss es aber nicht. Eine Seitenleiste mit Unternavigation steht typischerweise im <main> oder daneben, eine Fußnavigation im <footer>. Entscheidend ist nur, dass jeder Bereich einen unterscheidbaren Namen hat.
Wie viele <nav> sind zu viele?
Es gibt keine Zahl in der Spezifikation. Praktisch wird die Sprungliste ab etwa vier Navigationsbereichen unübersichtlich. Ich zeichne Hauptnavigation, Breadcrumb und – wenn vorhanden – die Fußnavigation aus; Sprachumschalter, „Weiterlesen“-Karten und Inhaltsverzeichnisse eines Artikels bleiben Listen in einem <div>.
Warum taucht mein <section> nicht in der Landmark-Liste auf?
Weil <section> nur mit zugänglichem Namen zur Rolle region wird. Setz aria-labelledby auf die id der enthaltenen Überschrift, dann erscheint es. Ohne Namen ist es absichtsvoll unsichtbar für die Landmark-Navigation – sonst wäre die Liste bei jeder längeren Seite voll.
Brauche ich <div> überhaupt noch, wenn es diese Elemente gibt?
Ja. Für Layout-Wrapper – ein Grid-Container, eine Zeile, ein Abstandshalter – ist <div> genau richtig und semantisch unauffällig. Falsch wird es erst, wenn ein <div> an der Stelle steht, an der ein benennbares Element hingehört. Die Abgrenzung klärt div vs. span.
Verwandte Themen
- Landmarks & Dokument-Outline – wie die Sprungliste entsteht und wie du sie prüfst
- article vs. section – die häufigste Stolperstelle im Gerüst
- Überschriften-Hierarchie – die zweite Navigationsebene neben den Landmarks
- Skip-Links – Sprungziel
#inhaltkorrekt umgesetzt - 2.4.1 Blöcke umgehen – das Kriterium hinter Landmarks und Skip-Links
- Formular-Semantik – was im
<search>-Container steht
Quellen
- ARIA in HTML (W3C – normative Zuordnung der impliziten Rollen, inklusive der Bedingung für
bannerundcontentinfo) - 4.3 Sections (WHATWG HTML Standard – Inhaltsmodelle von
header,nav,main,footer,hgroupund die aktuelle Definition der Outline) - Landmark Regions (W3C ARIA Authoring Practices – Empfehlungen zur Benennung und Anzahl von Landmarks)
- <search>: The generic search element (MDN Web Docs – Baseline-Status und Abgrenzung zur Trefferliste)
- Your skip link targets may not need tabindex=-1 to work properly (Manuel Matuzović, 2026 – Browsertests zum „sequential focus navigation starting point“ und die verbleibenden Ausnahmen)