Mobile Navigation kostenlos
Ein Menü zum Kopieren, das sich ansagt
Menüknopf, Menüpunkte, geschlossenes Panel: drei Stellen im Menü.
Ein-Datei-Baukasten
Ein Menü, zwei Ansichten, ein gemeinsamer Umschaltpunkt
Die mobile Navigation braucht kein Paket. Sie braucht sauberes HTML, einen sichtbaren Fokus und dieselbe Breitenregel in CSS und JavaScript.
nav → button + ulName, Zustand und echte Links@media (min-width: 48em)Unter 48em gestapelt, darüber in einer ZeilematchMedia('(min-width: 48em)')Öffnen, schließen, Escape und BreitenwechselMobil · geschlossenLinks sind nicht im Tab-Weg
ul[hidden]Keine unsichtbaren ZwischenstoppsDesktop · dauerhaft offenKnopf entfällt, Links bleiben erreichbar
48em, im Skript aber 50em, kann zwischen beiden Grenzen CSS schon Desktop zeigen, während das Skript noch den mobilen Zustand steuert. Ändern Sie die beiden Werte immer gemeinsam. Ohne JavaScript bleibt die Navigation verfügbar
Die Linkliste startet sichtbar, der Menüknopf startet mit hidden. Erst das geladene Skript zeigt den Knopf und klappt die mobile Liste ein. Fällt JavaScript aus, bleiben die Ziele erreichbar.
Die vollständige Datei zum Kopieren
Ersetzen Sie Marke, Links und Farben. Wenn Sie den Umschaltpunkt ändern, ändern Sie beide markierten 48em-Werte.
<!doctype html>
<html lang="de">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Mobile Navigation</title>
<style>
* { box-sizing: border-box; }
body {
margin: 0;
font-family: system-ui, sans-serif;
color: #111111;
background: #ffffff;
}
.seitenkopf {
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: space-between;
gap: 1rem;
padding: 1rem;
border-bottom: 2px solid #111111;
}
.marke { font-weight: 800; }
.menue-knopf {
display: inline-flex;
align-items: center;
gap: 0.5rem;
padding: 0.65rem 0.8rem;
color: #111111;
background: #ffffff;
border: 2px solid #111111;
font: inherit;
font-weight: 700;
}
.hauptnav { flex-basis: 100%; }
.menue-liste {
margin: 0;
padding: 0;
list-style: none;
}
.menue-liste[hidden] { display: none; }
.menue-liste a {
display: block;
padding: 0.75rem 0;
color: #111111;
}
.menue-liste a[aria-current="page"] {
font-weight: 800;
text-decoration-thickness: 0.2em;
}
.menue-knopf:focus-visible,
.menue-liste a:focus-visible {
outline: 3px solid #075bd8;
outline-offset: 3px;
}
/* UMSCHALTPUNKT 1 VON 2 */
@media (min-width: 48em) {
.hauptnav { flex-basis: auto; }
.menue-liste {
display: flex;
gap: 1.5rem;
}
.menue-liste a { padding: 0.5rem 0; }
}
</style>
</head>
<body>
<header class="seitenkopf">
<a class="marke" href="/">Nordlicht</a>
<button class="menue-knopf" id="menue-knopf" type="button"
aria-controls="hauptmenue" aria-expanded="false" hidden>
<span aria-hidden="true">☰</span>
<span>Menü</span>
</button>
<nav class="hauptnav" aria-label="Hauptnavigation">
<ul class="menue-liste" id="hauptmenue">
<li><a href="/" aria-current="page">Start</a></li>
<li><a href="/leistungen">Leistungen</a></li>
<li><a href="/ueber-uns">Über uns</a></li>
<li><a href="/kontakt">Kontakt</a></li>
</ul>
</nav>
</header>
<script>
const knopf = document.getElementById('menue-knopf');
const panel = document.getElementById('hauptmenue');
// UMSCHALTPUNKT 2 VON 2
const breite = window.matchMedia('(min-width: 48em)');
function setzeZustand(offen) {
knopf.setAttribute('aria-expanded', String(offen));
panel.hidden = !offen;
}
function passeAnBreiteAn() {
if (breite.matches) {
knopf.hidden = true;
panel.hidden = false;
knopf.setAttribute('aria-expanded', 'false');
} else {
knopf.hidden = false;
setzeZustand(false);
}
}
knopf.addEventListener('click', () => {
const istOffen = knopf.getAttribute('aria-expanded') === 'true';
setzeZustand(!istOffen);
});
document.addEventListener('keydown', (ereignis) => {
if (ereignis.key !== 'Escape' || panel.hidden) return;
setzeZustand(false);
knopf.focus();
});
breite.addEventListener('change', passeAnBreiteAn);
passeAnBreiteAn();
</script>
</body>
</html>Vier Änderungen, die das Beispiel zu Ihrem Menü machen
Tauschen Sie href und Linktexte. Setzen Sie aria-current="page" nur am Link der aktuellen Seite.
Ersetzen Sie „Nordlicht“. Bleibt Ihr Logo ein Bild, braucht es einen passenden Alternativtext; dekorative Zusätze bleiben stumm.
Passen Sie Hintergrund, Text und Fokusrahmen an. Der Fokus muss gegen seine direkte Umgebung deutlich sichtbar bleiben.
Ändern Sie beide UMSCHALTPUNKT-Werte zusammen und prüfen Sie die Breite direkt davor und danach.
Prüfen Sie Zustände statt nur Pixelbreiten
Diese kurze Route findet die typischen Fehler im Zusammenspiel.
- Ohne Skript: JavaScript deaktivieren. Die Links müssen sichtbar und mit Tab erreichbar bleiben.
- Mobil: Mit Enter öffnen und alle Links durchtabben. Geschlossen darf kein Link angesprungen werden.
- Rückweg: Einen Link fokussieren und Escape drücken. Das Panel schließt; der Fokus kehrt zum Knopf zurück.
- Grenze: Das Fenster über 48em und zurück ziehen. Auf Desktop verschwindet der Knopf, die Liste bleibt da.
Aus dem Prüfbericht
Drei Befunde am mobilen Menü
Kritisch Der Menüknopf zeigt nur drei Striche Regel button-name
Das Symbol trägt aria-hidden und lässt den Knopf namenlos. Ein aria-label benennt die Aktion, die das Menü öffnet.
Kritisch Menüpunkte, die nur ein Symbol zeigen Regel link-name
Ein Link aus reinem Symbol steht ohne Ziel in der Linkliste. Der Name des Punkts gehört sichtbar in den Link.
Zum Mitnehmen
Das mobile Menü, korrigiert
Ein Name, ein Zustand, ein wirklich geschlossenes Panel.
Korrektur in 3 Schritten ansehen
Den Menüknopf benennen
Das Symbol bleibt sichtbar und stumm. Ein aria-label liefert das Wort, aria-expanded sagt, ob das Panel offen ist.
KorrekturvergleichSchritt 1 · HTML Vorher
<button type="button" class="menu-toggle" aria-controls="menu"> <span aria-hidden="true">☰</span> </button>Nachher
<button type="button" class="menu-toggle" aria-controls="menu" aria-label="Menü öffnen" aria-expanded="false"> <span aria-hidden="true">☰</span> </button>Markierte Zeilen wurden geändert
So prüfen Sie es Gehen Sie mit Tab auf den Knopf. Ein Vorleseprogramm sagt „Menü öffnen, reduziert“.
Die Menüpunkte benennen
Der sichtbare Name des Punkts steht im Link. Symbole daneben bleiben für Vorleseprogramme verborgen.
KorrekturvergleichSchritt 2 · HTML Vorher
<li><a href="/leistungen"><span aria-hidden="true">›</span></a></li> <li><a href="/kontakt"><span aria-hidden="true">✉</span></a></li>Nachher
<li><a href="/leistungen">Leistungen</a></li> <li><a href="/kontakt">Kontakt</a></li>Markierte Zeilen wurden geändert
So prüfen Sie es Öffnen Sie die Linkliste eines Vorleseprogramms. Jeder Punkt nennt sein Ziel.
Das Panel wirklich schließen
hidden nimmt das Menü aus Bild und Tab-Weg. Ein aria-hidden allein lässt die Links erreichbar und stumm.
KorrekturvergleichSchritt 3 · HTML Vorher
<ul id="menu" aria-hidden="true"> <li><a href="/leistungen">Leistungen</a></li> </ul>Nachher
<ul id="menu" hidden> <li><a href="/leistungen">Leistungen</a></li> </ul>Markierte Zeilen wurden geändert
So prüfen Sie es Gehen Sie bei geschlossenem Menü mit Tab weiter. Der Fokus überspringt die Menüpunkte.
