Herzlich willkommen zum SELF-Treffen 2026
vom 24.04. – 26.04.2026
in Halle (Saale)
Navigation/Flyout-Menü
Gerade auf kleinen Bildschirmen und für Screenreader ist es oft wünschenswert, gleich zum Inhalt zu kommen, ohne sich lange mit der Navigation aufzuhalten. Hier gibt es zwei Möglichkeiten:
- ein Skip-Link ermöglicht es, die Navigation zu überspringen
- ein Popover versteckt die Navigation und klappt sie nur bei Bedarf aus.
Wir zeigen dir zwei Ansätze. Zuerst eine reine HTML-Variante mit einem popover, dann eine Komfort-Variante mit einem animerten Toggle-Button.
Inhaltsverzeichnis
Skiplink
Auf einem normalen Monitor ist die Navigation im Ausgangszustand eingeklappt und lässt sich mit einem Blick nach unten übergehen, während auf Screenreader angewiesene Benutzer sich durch alle Links durchtabben müssten. Mit einem Skipklink, der ganz am Anfang im Markup steht und auf den Hauptinhalt gerichtet ist, kannst du das Menü überspringen. Im Normalzustand ist der Skip-Link per CSS außerhalb des sichtbaren Bereichs positioniert.[1]
<a id="skip-link" class="visually-hidden" href="#content">zum Inhalt</a>
<nav>
<ul>
<li><a aria-current="page">Home</a></li>
<li><a href="#">Seite 2</a></li>
<li><a href="#">Seite 3</a></li>
<li><a href="#">Seite 4</a></li>
<li><a href="#">Kontakt</a></li>
</nav>
<main id="content">
Skiplinks werden am logischen Beginn des Dokuments notiert und enthalten zum Beispiel:
- zum Inhalt
- zur Navigation
- zur Sitesearch
Über die Klasse visually-hidden wird der Skiplink für Sehende ausgeblendet. Mit Software wie VoiceOver und anderen Screenreadern wird solch ein Link einfach als „Link zum Inhalt“ vorgelesen.
→ CSS/Tutorials/Sichtbarkeit von Elementen
Flyout-Menü mit popover
Um Platz für Inhalte zu schaffen, soll die Navigation nur bei Bedarf eingeblendet werden. Deshalb erweitern wir unsere responsive Navigation aus dem letzten Kapitel um einen Button. Im Grundzustand soll nur ein Navicon sichtbar sein - erst ein Klick auf dieses öffnet das Menü.
Im allgemeinen Gebrauch haben sich als Symbol oder Icon für einen Navigations-Button drei waagerechte Striche durchgesetzt. Deshalb wird ein solches Menü auch oft „Burgermenü“ oder „Hamburgermenü“ genannt. Du kannst bei Verwendung der Zeichencodierung utf-8 entweder direkt „☰“ oder ☰ eingeben.
<button class="close-icon"> × </button>
<button class="burger-icon">☰</button>
Diese Methode hat mehrere Nachteile:
- Bildschirmlesegeräte werden diese Symbole mit ihrem Namen vorlesen, was sehr verwirrend ist.
- ×: menu times, toggle button navigation 1 item
- ☰: menu trigram for heaven, toggle button navigation 1 item
- Durch die unterschiedliche Größe der Zeichen ist eine Formatierung mit CSS umständlich
Sowohl der Öffnen-Button als auch der in der Navigation befindliche Schließen-Button enthalten deshalb je zwei span-Elemente:
- Das erste Element erhält ein klar erkennbares Symbol wie das Hamburger-Icon, bzw. ein „X“ zum Schließen.
Diese sind durch das aria-hidden-Attribut für Screenreader unsichtbar - Für Screenreader gibt es einen Text, der vorgelesen wird.
Über die oben bereits vorgestellte Klasse.visually-hiddenwird dieser Text auf Bildschirmen ausgeblendet.
Popover
Ein Anklicken des Buttons triggert ein „Disclosure Widget“, das Inhalte auf- und zuklappen kann. Bekannt sind oft schon details- und dialog-Elemente. Hier verwenden wir ein nav-Element, das mit dem popover-Attribut aufklappbar wird:
<button popovertarget="main-nav">
<span aria-hidden="true">☰</span>
<span class="visually-hidden">Navigation</span>
</button>
<nav id="main-nav" popover>
<button popovertarget="main-nav" popovertargetaction="hide" class="close-btn">
<span aria-hidden="true">X</span>
<span class="visually-hidden">Schließen</span>
</button>
<ul>
<li><a href="" aria-current="page">Home</a></li>
<li><a href="#">Seite 2</a></li>
<li><a href="#">Seite 3</a></li>
<li><a href="#">Seite 4</a></li>
<li><a href="#">Kontakt</a></li>
</ul>
</nav>
Der Button wird über das popovertarget-Attribut mit der id des nav-Elements verbunden. Dieses Element erhält ein popover-Attribut. Ein Klick auf den Button öffnet die Navigation – ganz ohne JavaScript!
Die Navigation wird vom Browser geschlossen, wenn man
- die ESC-Taste drückt
- außerhalb des Popovers in die Seite klickt
- den Schließen-Button in der Navigation anklickt.
(Dieser ist über popovertarget mit der Navigation verbunden; popovertargetaction legt fest, dass das popover geschlossen werden soll.)[2]
Das alles passiert direkt im Browser - ohne zusätzliche Scripte!
Animation mit calc-size()
Mit CSS können wir das Aussehen ein bisschen finetunen. Eine Animation schiebt die Navigation nun auf:
[popover] {
height: 0;
overflow-y: clip;
transition:
height 0.25s allow-discrete,
display 0.25s allow-discrete;
}
[popover]:popover-open {
height: 15em; /* Fallback für ältere Browser! */
height: calc-size(auto, size);
width: 15em;
}
@starting-style {
[popover]:popover-open {
height: 0;
}
}
Es gibt bei den disclosure widgets ein altes Problem: Man kann keine transitions verwenden, da ursprünglich height: auto gilt.
Die Höhe des offenen popover wird mit der calc-size()-Funktion festgelegt. Die Werte auto, size verwenden den berechneten Wert von ‚auto‘ als Länge, die dann tatsächlich animiert werden kann. Das Schlüsselwort „size“ darin bezieht sich auf diesen ermittelten Wert, sodass „calc-size(auto, size)“ die einfachste Form ist – einfach „auto als Zahl“.
Ohne @starting-style hätte der Browser keinen „Vorher“-Zustand, von dem aus der Übergang erfolgen könnte. Wenn das Popover zum ersten Mal in der obersten Ebene erscheint, würde es sich also einfach ruckartig öffnen. @starting-style liefert diesen Anfangswert für die allererste Darstellung.
Was mit dieser popover-Variante, bzw. mit CSS nicht geht:
Auf großen Bildschirmen sollte das popover aufgeklappt sein, damit die Navigation sichtbar ist. Bei details gibt es ::details-content, welches man mit content-visibility einblenden könnte. Das entsprechende ::popover-open greift aber nur im geöffneten Zustand.
Deshalb benötigen wir eine zweite Version mit mehr Komfort und ein bisschen JavaScript:
Komfort-Variante mit Toggle-Button
Oft sieht man ein Flyout-Menü, bei dem ein Toggle-Button beide Funktionen (Auf- und Zuklappen) vereinigt. Der Übergang zwischen beiden Zuständen wird nicht nur durch das Aufschieben, sondern auch durch die Animation des Nav-Icons visualisiert.
In einer früheren Variante wurde dies mit JavaScript realisiert. Dieses Beispiel verlässt sich auf natives HTML, dessen Standardverhalten viele Features von sich aus integriert:
<button popovertarget="main-nav">
<span aria-hidden="true"><svg id="toggle">…</svg></span>
<span class="visually-hidden">Navigation</span>
</button>
<nav id="main-nav" popover>
<ul>
<li><a href="" aria-current="page">Home</a></li>
<li><a href="#">Seite 2</a></li>
<li><a href="#">Seite 3</a></li>
<li><a href="#">Seite 4</a></li>
<li><a href="#">Kontakt</a></li>
</ul>
</nav>
Gegenüber dem oberen Beispiel fehlt der Schließen-Button, dessen Funktionalität ja im Öffnen-Button integriert werden soll.
Der Button wird über das popovertarget-Attribut mit der id des nav-Elements verbunden. Dieses Element erhält ein popover-Attribut. Ein Klick auf den Button öffnet und schließt die Navigation – ganz ohne JavaScript! Da das hier nicht notierte popovertargetaction-Attribut den Defaultwert toggle besitzt, schaltet der Button die Zustände um.
Weiterhin sind keine ARIA-Hinweise (oder eine Änderung der Beschreibung in .visually-hidden) mehr notwendig, das popover wird vom Browser entsprechend interpretiert.
Animierte SVG-Icons
Icons werden heute nicht mehr mit Rastergrafiken, sondern mit SVG erzeugt. Neben der immer gestochenen Schärfe haben sie den Vorteil, dass sie mit CSS gestaltet und auch animiert werden können.
.line {
fill: none;
stroke: steelblue;
stroke-miterlimit: 8;
stroke-width: 5;
stroke-linecap: round;
transition: all 0.25s ease;
transform-origin: center;
}
#transform {
&:hover .top,
&:focus .top {
transform: rotate(45deg) translateY(10px);
}
&:hover .bottom,
&:focus .bottom {
transform: rotate(-45deg) translateY(-10px);
}
&:hover .middle,
&:focus .middle {
opacity: 0;
}
}
Hovere über den Buttons oder tabbe dich durch - aus einem Navicon wird ein Schließen-Icon.
Dabei werden verschiedene Techniken wie transform oder Line-Drawing verwendet.
CSS macht Zustände sichtbar
Das vorhandene HTML sorgt für die Funktionalität: Beim Klick auf den Button klappt die Navigation auf und zu, ein Screenreader signalisiert ohne weiteres Zutun den jeweiligen Zustand.
Mit CSS können wir diesen Prozess visualiseren. Wie wir aus dem Aufklappen ein Aufschieben machen, wurde bereits oben erklärt.
Das Navicon soll nun beim Toggle sein Erscheinungsbild ändern. Konventionell hätte man mit JavaScript auf den Klick gewartet und dann dem SVG eine Klasse hinzugefügt. Mittlerweile ist CSS so mächtig, dass es diese Zustände selbst erkennt. Dabei werden die Selektoren aber immer komplexer:
button[popovertarget="main-nav"] {
.line {
transform-box: fill-box;
fill: none;
stroke: steelblue;
stroke-miterlimit: 8;
stroke-width: 5;
stroke-linecap: round;
stroke-linejoin: round;
transition: all 0.25s ease;
transform-origin: center;
}
}
button[popovertarget="main-nav"]:has(~ nav:popover-open) {
.top { transform: translateY(20px) rotate(45deg); }
.bottom { transform: translateY(-20px) rotate(-45deg); }
.middle { opacity: 0; }
}
In den eckigen Klammern des Attributwert-Selektors befindet das popovertarget-Attribut, dessen Wert main-nav nur diesen Button selektiert.
Über den has()-Selektor können nun Nachfahren-Elemente bzw. Geschwister-Elemente gefunden werden. Wenn die Navigation geöffnet ist, wird die :popover-open-Pseudoklasse angesprochen und dann der Button, bzw. die Linien des SVGs transformiert, bzw. ausgeblendet.
Sichtbar auf großen Bildschirmen?
Was mit dieser popover-Variante, bzw. mit CSS nicht geht:
Auf großen Bildschirmen sollte das popover aufgeklappt sein, damit die Navigation sichtbar ist. Bei details gibt es ::details-content, welches man mit content-visibility einblenden könnte. Das entsprechende ::popover-open greift aber nur im geöffneten Zustand.
Deshalb benötigen wir eine zweite Version mit mehr Komfort und ein bisschen JavaScript:
Fazit
Solche Menüs eignen sich gleichermaßen für OnePager wie für kleinere Webauftritte.
Gegenüber der älteren Variante ist alles natives HTML und verzichtet auf JavaScript, dass eine Zugägnlichkeit in vielen Einzelschritten nachbaut.[3][4]
Für größere DropDown-Menüs stellt sich die Problematik des Auf- und Zuklappens bei jeder neuen Unterliste. Hier empfiehlt sich der Einsatz einer JavaScript-Lösung, wie sie im nächsten Kapitel vorgestellt wird.
Das 2019 geschriebene Tutorial einer zugänglichen Dropdown-Navigation mit summary und details wurde aus diesen Gründen depubliziert.
Weblinks
- ↑ SELF-Blog: Skipper ahoj! von Gunnar Bittersmann am 15.07.2018
- ↑
Information: Ausblick
Langfristig sollen die sperrigen Attributsnamen durch die schon vom dialog-Element bekannten command und commandfor-Attribute vereinheitlicht werden:Dies funktioniert (Stand März 2026) ebenfalls in allen modernen Browsern!<button commandfor="main-nav" command="show-popover"> Navigation ausklappen </button> <nav id="main-nav" popover> <button commandfor="main-nav" command="close"> ...
Da in älteren Browsern die Navigation aber dauerhaft verborgen wäre, ist der Ansatz mit popovertarget praxisnäher! - ↑ W3C: Fly-out Menus Tutorial der WAI
- ↑ Die vorhergehende Navigation basierte auf einem Entwurf von Ahmad Shadeed für a11ymatters.com.
a11ymatters.com: Accessible Mobile Navigation von Ahmad Shadeed
Ahmad verwendete viel Zeit auf eine komplexe Reihenfolge, damit die Navigations-Links auch ohne externe CSS- und JS-Ressourcen stets vorhanden waren. Das ist mit den nativem popover heute nicht mehr nötig!