HTML Navigation Accessibility
Skip-Links, ARIA-Attribute und Keyboard-Navigation - für eine barrierefreie Website.
Warum Accessibility für Navigation?
Nicht jeder nutzt eine Maus. Viele Menschen navigieren mit der Tastatur , nutzen Screenreader oder haben andere Einschränkungen. Eine barrierefreie Navigation ist nicht nur nett - in vielen Ländern ist sie gesetzlich vorgeschrieben (z.B. WCAG, BITV in Deutschland).
Wer profitiert?
- Blinde/sehbehinderte Nutzer (Screenreader)
- Motorisch eingeschränkte Nutzer (Tastatur)
- Nutzer mit temporären Einschränkungen
- Power-User die Tastatur bevorzugen
Was behandeln wir?
- Skip-Links zum Überspringen der Navigation
- ARIA-Attribute für Screenreader
- Keyboard-Navigation für Dropdowns
- Sichtbare Focus-States
Skip-Link (Sprungnavigation)
Ein Skip-Link ermöglicht es Tastatur- und Screenreader-Nutzern, direkt zum Hauptinhalt zu springen - ohne sich durch die gesamte Navigation zu tabben. Er ist normalerweise unsichtbar und erscheint erst bei Fokus.
Die HTML-Struktur
Der Skip-Link kommt
ganz an den Anfang
des
<body>
- noch vor dem Header!
<body>
<!-- Skip-Link: Ganz am Anfang! -->
<a href="#main-content" class="skip-link">Zum Inhalt springen</a>
<header>
<nav>
<!-- Hier ist die lange Navigation... -->
</nav>
</header>
<main id="main-content">
<!-- Hauptinhalt - hier springt der Link hin -->
</main>
</body>
Demo: Klicke in die Box und drücke Tab ⇥ , um den Skip-Link zu sehen:
Das CSS für den Skip-Link
/* Skip-Link: Versteckt, bis fokussiert */
.skip-link {
position: absolute;
top: -100px; /* Außerhalb des Viewports */
left: 50%;
transform: translateX(-50%);
background: var(--accent-blue);
color: white;
padding: 0.75rem 1.5rem;
border-radius: 0 0 8px 8px;
text-decoration: none;
font-weight: 600;
z-index: 9999; /* Über allem anderen */
transition: top 0.3s ease;
}
/* Bei Fokus (Tab-Taste): Sichtbar machen */
.skip-link:focus {
top: 0;
outline: 2px solid var(--accent-cyan);
outline-offset: 2px;
}
Stell dir vor, du müsstest bei jeder Seite erst 20+ Navigationslinks durchtabben, bevor du zum Inhalt kommst. Für Tastaturnutzer ist das Alltag - ein Skip-Link macht den Unterschied zwischen frustrierend und nutzbar.
Sichtbare Focus-States
Wenn Nutzer mit Tab durch die Seite navigieren, müssen sie sehen können, wo sie gerade sind . Der Browser zeigt standardmäßig einen Fokus-Ring - aber viele Designer entfernen ihn. Das ist ein großer Fehler!
/* ❌ NIEMALS SO! */
*:focus {
outline: none;
}
a:focus {
outline: 0;
}
Das entfernt den Fokus-Indikator komplett - Tastaturnutzer sind dann blind!
Guter vs. schlechter Focus
Demo: Tabbe durch beide Navigationen Tab ⇥ und sieh den Unterschied:
Guter Focus:
Schlechter Focus (outline: none):
Eigenen Focus-Style gestalten
Wenn dir der Standard-Fokusring nicht gefällt, ersetze ihn - aber entferne ihn nicht!
/* ✅ Eigener Focus-Style */
a:focus {
outline: 2px solid var(--accent-blue);
outline-offset: 2px;
}
/* Oder mit box-shadow für rundere Ecken */
button:focus {
outline: none; /* Nur OK wenn Ersatz vorhanden! */
box-shadow: 0 0 0 3px var(--accent-blue);
}
/* Focus nur bei Tastatur, nicht bei Mausklick */
a:focus-visible {
outline: 2px solid var(--accent-blue);
outline-offset: 2px;
}
-
:focus- Wird bei JEDEM Fokus aktiv (Maus + Tastatur) -
:focus-visible- Nur bei Tastatur-Fokus (moderner, aber check Browser-Support)
Mehr zu Focus-Styling
Hier geht es um die Accessibility-Pflicht für Focus-States. Wenn du wissen willst, wie du sie schön gestaltest (Animationen, verschiedene Varianten), schau ins CSS Navigation States Tutorial.
ARIA-Attribute für Screenreader
ARIA (Accessible Rich Internet Applications) sind Attribute, die zusätzliche Informationen für Screenreader bereitstellen. Für Navigationen besonders wichtig:
Navigation benennen
<!-- Hauptnavigation -->
<nav aria-label="Hauptnavigation">
<ul>...</ul>
</nav>
<!-- Footer-Navigation -->
<nav aria-label="Footer-Links">
<ul>...</ul>
</nav>
<!-- Breadcrumbs -->
<nav aria-label="Breadcrumb">
<ol>...</ol>
</nav>
Aktuelle Seite markieren
Mit
aria-current="page"
sagst du Screenreadern, welcher Link die aktuelle Seite ist:
<nav aria-label="Hauptnavigation">
<ul>
<li><a href="/">Home</a></li>
<li><a href="/about/" aria-current="page">Über uns</a></li>
<li><a href="/contact/">Kontakt</a></li>
</ul>
</nav>
Demo: "Über uns" ist als aktuelle Seite markiert:
Das Attribut kannst du auch für CSS-Styling nutzen:
/* Aktuelle Seite hervorheben */
nav a[aria-current="page"] {
background: var(--accent-blue);
color: white;
font-weight: 600;
}
Dropdowns mit ARIA
Für Dropdowns brauchst du mehrere ARIA-Attribute, damit Screenreader verstehen, was passiert:
<li class="dropdown">
<!-- Button statt Link für Dropdown-Trigger! -->
<button
aria-expanded="false"
aria-haspopup="true"
aria-controls="dropdown-themen">
Themen ▼
</button>
<ul id="dropdown-themen" role="menu">
<li role="menuitem"><a href="/html/">HTML</a></li>
<li role="menuitem"><a href="/css/">CSS</a></li>
<li role="menuitem"><a href="/js/">JavaScript</a></li>
</ul>
</li>
Wichtige ARIA-Attribute erklärt
| Attribut | Bedeutung |
|---|---|
aria-label |
Benennt die Navigation (z.B. "Hauptnavigation", "Footer-Links") |
aria-current |
Markiert die aktuelle Seite (
"page"
) oder Position
|
aria-expanded |
Zeigt an, ob ein Dropdown offen (
true
) oder geschlossen (
false
) ist
|
aria-haspopup |
Signalisiert, dass ein Element ein Popup/Dropdown öffnet |
aria-controls |
Verknüpft Button mit dem gesteuerten Element (per ID) |
Für Dropdown-Trigger solltest du einen
<button>
verwenden, keinen
<a>
-Link! Links sind für Navigation zu anderen Seiten, Buttons für Aktionen auf der
aktuellen Seite.
Keyboard-Navigation für Dropdowns
Nutzer müssen Dropdowns komplett mit der Tastatur bedienen können. Das bedeutet: Öffnen, Navigieren und Schließen ohne Maus.
Erwartetes Verhalten
| Taste | Aktion |
|---|---|
| Tab | Zum nächsten fokussierbaren Element |
| Enter / Space | Dropdown öffnen/schließen |
| ↓ Pfeil runter | Zum nächsten Item im Dropdown |
| ↑ Pfeil hoch | Zum vorherigen Item im Dropdown |
| Escape | Dropdown schließen, Focus zurück auf Button |
| Home | Zum ersten Item (optional) |
| End | Zum letzten Item (optional) |
Das JavaScript
// Keyboard-Support für Dropdown-Buttons
document.querySelectorAll('.dropdown button').forEach(button => {
button.addEventListener('keydown', function(e) {
const dropdown = this.nextElementSibling;
const isOpen = dropdown.classList.contains('open');
switch(e.key) {
case 'Enter':
case ' ': // Leertaste
e.preventDefault();
toggleDropdown(this, dropdown);
break;
case 'Escape':
if (isOpen) {
closeDropdown(this, dropdown);
this.focus(); // Focus zurück auf Button
}
break;
case 'ArrowDown':
e.preventDefault();
if (isOpen) {
// Zum ersten Link im Dropdown
dropdown.querySelector('a')?.focus();
} else {
openDropdown(this, dropdown);
}
break;
}
});
});
// Navigation innerhalb des Dropdowns
document.querySelectorAll('.dropdown-menu a').forEach(link => {
link.addEventListener('keydown', function(e) {
const items = [...this.closest('ul').querySelectorAll('a')];
const index = items.indexOf(this);
const button = this.closest('.dropdown').querySelector('button');
const dropdown = this.closest('ul');
switch(e.key) {
case 'ArrowDown':
e.preventDefault();
// Zum nächsten Item (oder zurück zum ersten)
const nextIndex = (index + 1) % items.length;
items[nextIndex].focus();
break;
case 'ArrowUp':
e.preventDefault();
// Zum vorherigen Item (oder zum letzten)
const prevIndex = (index - 1 + items.length) % items.length;
items[prevIndex].focus();
break;
case 'Escape':
closeDropdown(button, dropdown);
button.focus();
break;
case 'Tab':
// Bei Tab: Dropdown schließen
closeDropdown(button, dropdown);
break;
}
});
});
// Hilfsfunktionen
function openDropdown(button, menu) {
menu.classList.add('open');
button.setAttribute('aria-expanded', 'true');
}
function closeDropdown(button, menu) {
menu.classList.remove('open');
button.setAttribute('aria-expanded', 'false');
}
function toggleDropdown(button, menu) {
const isOpen = menu.classList.contains('open');
if (isOpen) {
closeDropdown(button, menu);
} else {
openDropdown(button, menu);
}
}
Accessibility-Checkliste
Nutze diese Checkliste, um deine Navigation auf Barrierefreiheit zu prüfen:
- Skip-Link vorhanden und funktioniert
-
<nav>mitaria-labelbeschriftet - Alle Links per Tab erreichbar
-
Sichtbarer Focus-Indikator
- nie
outline: none! - Dropdowns öffnen mit Enter / Space
- Escape schließt Dropdowns
- ↑ ↓ Pfeiltasten navigieren im Dropdown
-
aria-expandedwird bei Toggle aktualisiert -
Aktuelle Seite mit
aria-current="page"markiert - Kontrastverhältnis mindestens 4.5:1
- Touch-Targets mindestens 44×44px
- Tastatur-Test: Navigiere nur mit Tab, Enter, Pfeiltasten, Escape
- Screenreader: VoiceOver (Mac), NVDA (Windows, kostenlos)
- Browser-Extensions: axe DevTools, WAVE, Lighthouse
- Kontrast-Check: WebAIM Contrast Checker
Jetzt weißt du, was für Accessibility wichtig ist. Im Tutorial CSS Navigation States lernst du, wie du Hover, Focus und Active States auch optisch ansprechend gestaltest - mit Animationen, verschiedenen Varianten und Best Practices fürs Design.
Teste es selbst
Wende das Gelernte direkt an - probiere den Code aus dem Tutorial aus oder experimentiere mit eigenen Ideen.
Editor öffnen
Mehr aus HTML
Tutorials werden geladen...