Hauptnavigation für eine Website erstellen

In dieser Anleitung wird beschrieben, wie Sie eine barrierefreie Hauptnavigation einer Website erstellen. Sie erfahren mehr über semantisches HTML, Barrierefreiheit und wie die Verwendung von ARIA-Attributen manchmal mehr Schaden als Nutzen anrichten kann.

Manuel Matuzović
Manuel Matuzović

Es gibt viele verschiedene Möglichkeiten, die Hauptnavigation einer Website zu erstellen, was Stil, Funktionalität und das zugrunde liegende Markup und die semantischen Informationen angeht. Wenn die Implementierung zu minimalistisch ist, funktioniert sie zwar für die meisten Nutzer, die Nutzererfahrung (User Experience, UX) ist jedoch möglicherweise nicht optimal. Wenn sie zu kompliziert ist, kann das Nutzer verwirren oder sie sogar daran hindern, überhaupt darauf zuzugreifen.

Bei den meisten Websites sollten Sie etwas entwickeln, das weder zu einfach noch zu kompliziert ist.

Schicht für Schicht bauen

In dieser Anleitung beginnen Sie mit einer einfachen Einrichtung und fügen nach und nach Funktionen hinzu, bis Sie genau die Informationen, das Design und die Funktionen anbieten, die den meisten Nutzern gefallen. Dazu nutzen Sie das Prinzip der progressiven Verbesserung, bei dem Sie mit der grundlegendsten und robustesten Lösung beginnen und nach und nach Funktionsschichten hinzufügen. Wenn eine Ebene aus irgendeinem Grund nicht funktioniert, funktioniert die Navigation trotzdem, da automatisch auf die darunter liegende Ebene zurückgegriffen wird.

Grundstruktur

Für eine grundlegende Navigation benötigen Sie zwei Dinge: <a>-Elemente und ein paar Zeilen CSS, um das Standard-Styling und -Layout Ihrer Links zu verbessern.

<a href="/home">Home</a>
<a href="/about-us">About us</a>
<a href="/pricing">Pricing</a>
<a href="/contact">Contact</a>
/* Define variables for your colors */
:root {
  --color-shades-dark: rgb(25, 25, 25);
}

/* Use the alternative box model
Details: <https://web.dev/learn/css/box-model/> */
*{
  box-sizing: border-box;
}

/* Basic font styling */
body {
  font-family: Segoe UI, system-ui, -apple-system, sans-serif;
  font-size: 1.6rem;
}

/* Link styling */
a {
  --text-color: var(--color-shades-dark);
  border-block-end: 3px solid var(--border-color, transparent);
  color: var(--text-color);
  display: inline-block;
  margin-block-end: 0.5rem; /* See note at the bottom of this chapter */
  margin-inline-end: 0.5rem;
  padding: 0.1rem;
  text-decoration: none;
}

/* Change the border-color on :hover and :focus */
a:where(:hover, :focus) {
  --border-color: var(--text-color);
}
Sehen Sie sich Schritt 1: Einfache HTML- und CSS-Code auf CodePen an.

Das funktioniert für die meisten Nutzer gut, unabhängig davon, wie sie auf die Website zugreifen. Die Navigation ist mit einer Maus, einer Tastatur, einem Touchgerät oder einem Screenreader zugänglich, es gibt aber Verbesserungsmöglichkeiten. Sie können dieses grundlegende Muster mit zusätzlichen Funktionen und Informationen erweitern.

Sie haben folgende Möglichkeiten:

  • Heben Sie die aktive Seite hervor.
  • Die Anzahl der Elemente für Nutzer von Screenreadern ansagen
  • Fügen Sie eine Markierung hinzu und ermöglichen Sie Nutzern von Screenreadern, über eine Tastenkombination direkt auf die Navigation zuzugreifen.
  • Blenden Sie die Navigation in schmalen Ansichten aus.
  • Die Darstellung des Fokus wurde verbessert.

Aktive Seite hervorheben

Um die aktive Seite hervorzuheben, können Sie dem entsprechenden Link eine Klasse hinzufügen.

<a href="/about-us" class="active-page">About us</a>

Das Problem bei diesem Ansatz ist, dass die Information, welcher Link aktiv ist, rein visuell vermittelt wird. Ein blinder Nutzer eines Screenreaders konnte keinen Unterschied zwischen der aktiven Seite und anderen Seiten feststellen. Glücklicherweise bietet der ARIA-Standard (Accessible Rich Internet Applications) eine Möglichkeit, diese Informationen auch semantisch zu kommunizieren. Verwenden Sie das Attribut und den Wert aria-current="page" anstelle einer Klasse.

aria-current (Status) gibt das Element an, das das aktuelle Element in einem Container oder einer Gruppe ähnlicher Elemente darstellt. Ein Seitentoken, das einen Link innerhalb einer Reihe von Paginierungslinks angibt. Der Link ist visuell so gestaltet, dass er die aktuell angezeigte Seite darstellt. [Accessible Rich Internet Applications (WAI-ARIA) 1.1](https://www.w3.org/TR/wai-aria/#aria-current)

Mit dem zusätzlichen Attribut liest ein Screenreader jetzt etwas wie „aktuelle Seite, Link, Über uns“ anstelle von nur „Link, Über uns“ vor.

<a href="/about-us" aria-current="page" class="active-page">About us</a>

Ein praktischer Nebeneffekt ist, dass Sie das Attribut verwenden können, um den aktiven Link in CSS auszuwählen, wodurch die Klasse active-page obsolet wird.

<a href="/home">Home</a>
<a href="/about-us" aria-current="page">About us</a>
<a href="/pricing">Pricing</a>
<a href="/contact">Contact</a>
/* Change border-color and color for the active page */
[aria-current="page"] {
  --border-color: var(--color-highlight);
  --text-color: var(--color-highlight);
}
Sehen Sie sich Schritt 2: Aktive Seite in CodePen hervorheben an.

Anzahl der Artikel ansagen

Sehende Nutzer erkennen an der Navigation, dass sie nur vier Links enthält. Ein blinder Nutzer eines Screenreaders kann diese Informationen nicht so schnell erhalten. Möglicherweise muss er sich durch die gesamte Liste der Links arbeiten. Das ist möglicherweise kein Problem, wenn die Liste wie in diesem Beispiel kurz ist. Wenn sie jedoch 40 Links enthält, kann diese Aufgabe mühsam sein. Wenn ein Screenreader-Nutzer im Voraus weiß, dass die Navigation viele Links enthält, kann er sich für eine andere, effizientere Navigationsmethode entscheiden, z. B. die Websitesuche.
Eine gute Möglichkeit, die Anzahl der Elemente vorab zu kommunizieren, besteht darin, jeden Link in ein Listenelement (<li>) einzubetten, das in einer ungeordneten Liste (<ul>) verschachtelt ist.

<ul>
  <li>
     <a href="/home">Home</a>
  </li>
  <li>
    <a href="/about-us" aria-current="page">About us</a>
  </li>
  <li>
    <a href="/pricing">Pricing</a>
  </li>
  <li>
    <a href="/contact">Contact</a>
  </li>
</ul>

Wenn ein Nutzer mit einem Screenreader die Liste findet, sagt die Software etwas wie „Liste, 4 Elemente“.

Hier sehen Sie eine Demo der Navigation mit dem Screenreader NVDA unter Windows.

Jetzt müssen Sie das Design so anpassen, dass es wieder so aussieht wie zuvor.

/* Remove the default list styling and create a flexible layout for the list */
ul {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

/* Basic link styling */
a {
  --text-color: var(--color-shades-dark);

  border-block-end: 3px solid var(--border-color, transparent);
  color: var(--text-color);
  padding: 0.1rem;
  text-decoration: none;
}

Die Verwendung von Listen kann für Nutzer von Screenreadern viele Vorteile haben:

  • Sie können die Gesamtzahl der Artikel abrufen, bevor sie mit ihnen interagieren.
  • Sie können Tastenkürzel verwenden, um von einem Listenelement zum nächsten zu springen.
  • Sie können Tastenkürzel verwenden, um von Liste zu Liste zu springen.
  • Der Screenreader kann den Index des aktuellen Elements ansagen (z. B. „Listenelement, zwei von vier“).

Wenn die Seite ohne CSS dargestellt wird, werden die Links in der Liste als zusammenhängende Gruppe von Elementen und nicht nur als Stapel von Links angezeigt.

Ein wichtiges Detail zu VoiceOver in Safari ist, dass Sie alle diese Vorteile verlieren, wenn Sie list-style: none festlegen. Dies geschieht absichtlich. Das WebKit-Team hat beschlossen, die Listensemantik zu entfernen, wenn eine Liste nicht wie eine Liste aussieht. Je nach Komplexität Ihrer Navigation kann dies ein Problem sein oder nicht. Die Navigation ist weiterhin nutzbar und die Änderung betrifft nur VoiceOver in Safari. VoiceOver in Chrome oder Firefox sowie andere Screenreader wie NVDA geben die Anzahl der Elemente weiterhin an. Andererseits können die semantischen Informationen in einigen Situationen sehr nützlich sein. Um diese Entscheidung zu treffen, sollten Sie die Navigation mit echten Screenreader-Nutzern testen und deren Feedback einholen. Wenn Sie möchten, dass VoiceOver in Safari wie alle anderen Screenreader funktioniert, können Sie das Problem umgehen, indem Sie die ARIA-Listenrolle explizit für die <ul> festlegen. Dadurch wird das Verhalten auf den Zustand vor dem Entfernen des Listenstils zurückgesetzt. Optisch bleibt die Liste unverändert.

<ul role="list">
  <li>
     <a href="/home">Home</a>
  </li>
  ...
</ul>
Sehen Sie sich Schritt 3: Anzahl der Elemente in CodePen ansagen an.

Sehenswürdigkeit hinzufügen

Mit wenig Aufwand haben Sie bereits große Verbesserungen für Nutzer von Screenreadern vorgenommen. Es gibt jedoch noch etwas, das Sie tun können. Die Navigation ist semantisch immer noch nur eine Liste von Links und es ist schwer zu erkennen, dass diese Liste die Hauptnavigation Ihrer Website ist. Sie können diese normale Liste in eine Navigationsliste umwandeln, indem Sie das Element <ul> in ein <nav>-Element einschließen.

Die Verwendung des Elements <nav> bietet mehrere Vorteile. Ein Screenreader kündigt beispielsweise „Navigation“ an, wenn der Nutzer damit interagiert, und fügt der Seite eine Markierung hinzu. Markierungen sind spezielle Bereiche auf der Seite, z. B. <header>, <footer> oder <main>, zu denen ein Screenreader springen kann. Markierungen auf einer Seite können hilfreich sein, da Nutzer von Screenreadern so direkt auf wichtige Bereiche der Seite zugreifen können, ohne mit dem Rest der Seite interagieren zu müssen. Sie können beispielsweise in NVDA die Taste D drücken, um von einer Markierung zur nächsten zu springen. In VoiceOver können Sie mit dem Rotor alle Markierungen auf der Seite auflisten. Drücken Sie dazu VO + U.

Eine Liste mit vier Markierungen: Banner, Navigation, Hauptseite, Inhaltsinformationen.
Rotor in VoiceOver mit einer Liste aller Markierungen auf einer Seite.

In dieser Liste sehen Sie vier Markierungen: Banner ist das Element <header>, Navigation ist das Element <nav>, Haupt ist das Element <main> und Inhaltsinformationen ist das Element <footer>. Diese Liste sollte nicht zu lang sein. Sie sollten nur wichtige Teile Ihrer Benutzeroberfläche als Markierungen kennzeichnen, z. B. die Websitesuche, eine lokale Navigation oder eine Paginierung.

Wenn Sie eine websiteweite Navigation, eine lokale Navigation für die Seite und eine Paginierung auf einer einzelnen Seite haben, können Sie auch drei <nav>-Elemente haben. Das ist in Ordnung, aber jetzt gibt es drei Navigationsmerkmale, die semantisch alle gleich aussehen. Es ist schwer, sie zu unterscheiden, es sei denn, Sie kennen die Struktur der Seite sehr gut.

Bild mit drei Wahrzeichen, auf denen jeweils „Navigation“ steht
Der VoiceOver-Rotor mit drei nicht gekennzeichneten Navigationspunkten.

Damit sie sich unterscheiden lassen, sollten Sie sie mit aria-labelledby oder aria-label kennzeichnen.

<nav aria-label="Main">
    <ul>
      <li>
         <a href="/home">Home</a>
      </li>
      ...
  </ul>
</nav>
...
<nav aria-label="Select page">
    <ul>
      <li>
         <a href="/page-1">1</a>
      </li>
      ...
    </ul>
</nav>

Wenn das ausgewählte Label bereits auf der Seite vorhanden ist, können Sie stattdessen aria-labelledby verwenden und mit dem Attribut id auf das vorhandene Label verweisen.

<nav aria-labelledby="pagination_heading">
  <h2 id="pagination_heading">Select a page</h2>
  <ul>
    <li>
       <a href="/page-1">1</a>
    </li>
    ...
  </ul>
</nav>

Ein prägnantes Label reicht aus. Verwenden Sie keine Begriffe wie „Navigation“ oder „Menü“, da diese Informationen den Nutzern bereits vom Screenreader zur Verfügung gestellt werden.

Landmarken
Voiceover mit den Markierungen „Banner“, „Hauptnavigation“, „Hauptseite“, „Seitennavigation“, „Seitennavigation auswählen“ und „Inhaltsinformationen“.
Sehen Sie sich Schritt 4: Markierung in CodePen hinzufügen an.

Navigation in schmalen Ansichten ausblenden

Ich bin kein großer Fan davon, die Hauptnavigation bei schmalen Ansichten auszublenden, aber wenn die Liste der Links zu lang wird, gibt es keine andere Möglichkeit. In diesem Fall sehen Nutzer anstelle der Liste eine Schaltfläche mit der Bezeichnung „Menü“ oder ein Dreistrich-Menü oder eine Kombination aus beiden. Wenn Sie auf die Schaltfläche klicken, wird die Liste angezeigt oder ausgeblendet. Wenn Sie grundlegendes JavaScript und CSS beherrschen, ist das eine machbare Aufgabe. Sie müssen jedoch einige Dinge in Bezug auf UX und Barrierefreiheit beachten.

  • Sie müssen die Liste auf barrierefreie Weise ausblenden.
  • Die Navigation muss über die Tastatur zugänglich sein.
  • Die Navigation muss klar zeigen, ob sie sichtbar ist oder nicht.

Schaltfläche „Dreistrich-Menü“ hinzufügen

Da Sie das Prinzip der progressiven Verbesserung befolgen, sollten Sie darauf achten, dass Ihre Navigation auch bei deaktiviertem JavaScript funktioniert und Sinn ergibt.
Das erste, was Ihre Navigation benötigt, ist eine Dreistrich-Schaltfläche. Sie erstellen es in HTML in einem Vorlagenelement, klonen es in JavaScript und fügen es der Navigation hinzu.

Eine Seite mit einer Dreistrich-Schaltfläche.
Ergebnis: Statt Links wird in der Navigation auf schmalen Ansichten eine Dreistrich-Schaltfläche angezeigt.
<nav id="mainnav">
  ...
</nav>

<template id="burger-template">
  <button type="button" aria-expanded="false" aria-label="Menu" aria-controls="mainnav">
    <svg width="24" height="24" aria-hidden="true">
      <path d="M3 18h18v-2H3v2zm0-5h18v-2H3v2zm0-7v2h18V6H3z">
    </svg>
  </button>
</template>
  1. Das Attribut aria-expanded gibt der Screenreader-Software an, ob das Element, das die Schaltfläche steuert, maximiert ist oder nicht.
  2. aria-label gibt der Schaltfläche einen sogenannten barrierefreien Namen, eine Textalternative für das Dreistrich-Menü.
  3. Sie verbergen <svg> mit aria-hidden vor Hilfstechnologien, da es bereits ein Textlabel von aria-label hat.
  4. aria-controls gibt Hilfstechnologien, die das Attribut unterstützen (z. B. JAWS), an, welches Element die Schaltfläche steuert.
const nav = document.querySelector('#mainnav')
const list = nav.querySelector('ul');
const burgerClone = document.querySelector('#burger-template').content.cloneNode(true);
const button = burgerClone.querySelector('button');

// Toggle aria-expanded attribute
button.addEventListener('click', e => {
  // aria-expanded="true" signals that the menu is currently open
  const isOpen = button.getAttribute('aria-expanded') === "true"
  button.setAttribute('aria-expanded', !isOpen);
});

// Hide list on keydown Escape
nav.addEventListener('keyup', e => {
  if (e.code === 'Escape') {
    button.setAttribute('aria-expanded', false);
  }
});

// Add the button to the page
nav.insertBefore(burgerClone, list);
  1. Es ist praktisch, wenn Nutzer die Navigation jederzeit schließen können, z. B. durch Drücken der Esc-Taste.
  2. Es ist wichtig, insertBefore anstelle von appendChild zu verwenden, da die Schaltfläche das erste Element in der Navigation sein sollte. Wenn ein Nutzer mit Tastatur oder Screenreader nach dem Klicken auf die Schaltfläche die Tabulatortaste drückt, erwartet er, dass der Fokus auf dem ersten Element in der Liste liegt. Wenn die Schaltfläche nach der Liste kommt, ist das nicht der Fall.

Als Nächstes setzen Sie das Standard-Styling der Schaltfläche zurück und sorgen dafür, dass sie nur in schmalen Darstellungsbereichen sichtbar ist.

@media (min-width: 48em) {
  nav {
    --nav-button-display: none;
  }
}

/* Reset button styling */
button {
  all: unset;
  display: var(--nav-button-display, flex);
}
Sehen Sie sich Schritt 5: Dreistrich-Schaltfläche in CodePen hinzufügen an.

Liste ausblenden

Bevor Sie die Liste ausblenden, positionieren und gestalten Sie die Navigation und die Liste so, dass das Layout für schmale Ansichten optimiert ist, aber auch auf größeren Bildschirmen gut aussieht.
Entfernen Sie zuerst das <nav> aus dem natürlichen Fluss der Seite und platzieren Sie es oben im Darstellungsbereich.

@media (min-width: 48em) {
  nav {
    --nav-button-display: none;
    --nav-position: static;
  }
}

nav {
  position: var(--nav-position, fixed);
  inset-block-start: 1rem;
  inset-inline-end: 1rem;
}

Ändern Sie als Nächstes das Layout für schmale Darstellungsbereiche, indem Sie eine neue benutzerdefinierte Property (—-nav-list-layout) hinzufügen. Das Layout ist standardmäßig als Spalte konfiguriert und wechselt auf größeren Bildschirmen zu Zeilen.

@media (min-width: 48em) {
  nav {
    --nav-button-display: none;
    --nav-position: static;
  }

  ul {
    --nav-list-layout: row;
  }
}

ul {
  display: flex;
  flex-direction: var(--nav-list-layout, column);
  flex-wrap: wrap;
  gap: 1rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

Die Navigation sollte auf schmalen Ansichten in etwa so aussehen.

Die Seite mit der Navigationsliste und der Dreistrich-Schaltfläche.
Sowohl die Dreistrich-Schaltfläche als auch die Liste sind oben im Viewport platziert.

Für die Liste ist natürlich CSS erforderlich. Wir verschieben es in die obere Ecke, lassen es vertikal den gesamten Bildschirm füllen und wenden eine background-color und eine box-shadow an.

@media (min-width: 48em) {
  nav {
    --nav-button-display: none;
    --nav-position: static;
  }
  
  ul {
    --nav-list-layout: row;
    --nav-list-position: static;
    --nav-list-padding: 0;
    --nav-list-height: auto;
    --nav-list-width: 100%;
    --nav-list-shadow: none;
  }
}

ul {
  background: rgb(255, 255, 255);
  box-shadow: var(--nav-list-shadow, -5px 0 11px 0 rgb(0 0 0 / 0.2));
  display: flex;
  flex-direction: var(--nav-list-layout, column);
  flex-wrap: wrap;
  gap: 1rem;
  height: var(--nav-list-height, 100vh);
  list-style: none;
  margin: 0;
  padding: var(--nav-list-padding, 2rem);
  position: var(--nav-list-position, fixed);
  inset-block-start: 0; /* Logical property. Equivalent to top: 0; */
  inset-inline-end: 0; /* Logical property. Equivalent to right: 0; */
  width: var(--nav-list-width, min(22rem, 100vw));
}

button {
  all: unset;
  display: var(--nav-button-display, flex);
  position: relative;
  z-index: 1;
}

Auf schmalen Ansichten sollte die Liste in etwa so aussehen, also eher wie eine Seitenleiste als eine einfache Liste.

Die Navigationsliste wird geöffnet.

Verstecken Sie die Liste abschließend und zeigen Sie sie nur an, wenn der Nutzer einmal auf die Schaltfläche klickt. Wenn er noch einmal klickt, wird sie wieder ausgeblendet. Es ist wichtig, nur die Liste und nicht die gesamte Navigation auszublenden, da das Ausblenden der Navigation auch bedeutet, dass ein wichtiges Orientierungsmerkmal ausgeblendet wird.

Sie haben der Schaltfläche bereits ein Klickereignis hinzugefügt, um den Wert des Attributs aria-expanded umzuschalten. Sie können diese Informationen als Bedingung für das Ein- und Ausblenden der Liste in CSS verwenden.

@media (min-width: 48em) {
  ul {
    --nav-list-visibility: visible;
  }
}

ul {
  visibility: var(--nav-list-visibility, visible);
}

/* Hide the list on narrow viewports, if it comes after an element with
   aria-expanded set to "false". */
[aria-expanded="false"] + ul {
  visibility: var(--nav-list-visibility, hidden);
}

Verwenden Sie zum Ausblenden der Liste eine Property-Deklaration wie visibility: hidden oder display: none anstelle von opacity: 0 oder translateX(100%). Mit diesen Eigenschaften wird sichergestellt, dass die Links nicht fokussiert werden können, wenn die Navigation ausgeblendet ist. Wenn Sie opacity oder translate verwenden, werden die Inhalte visuell entfernt. Die Links sind dann zwar nicht sichtbar, aber über die Tastatur weiterhin zugänglich. Das kann verwirrend und frustrierend sein. Mit visibility oder display wird es visuell ausgeblendet und kann nicht mehr aufgerufen werden. Es ist dann für alle Nutzer nicht sichtbar.

Sehen Sie sich Schritt 6: Liste ausblenden an.

Liste animieren

Warum Sie visibility: hidden; anstelle von display: none; verwenden sollten? Weil Sie die Sichtbarkeit animieren können. Es hat nur zwei Zustände, hidden und visible, kann aber mit einer anderen Eigenschaft wie transform oder opacity kombiniert werden, um einen Einblendungs- oder Einblendungseffekt zu erzielen. Das funktioniert nicht mit „display: none“, da das Display-Attribut nicht animiert werden kann.

Die folgenden CSS-Übergänge opacity erzeugen einen Ein- und Ausblendeffekt.

ul {
  transition: opacity 0.6s linear, visibility 0.3s linear;
  visibility: var(--nav-list-visibility, visible);
}

[aria-expanded="false"] + ul {
  opacity: 0;
  visibility: var(--nav-list-visibility, hidden);
}

Wenn Sie stattdessen Bewegungen animieren möchten, sollten Sie die Eigenschaft transition in eine prefers-reduced-motion-Medienabfrage einschließen, da Animationen bei einigen Nutzern Übelkeit, Schwindel und Kopfschmerzen auslösen können.

ul {
  visibility: var(--nav-list-visibility, visible);
}

@media (prefers-reduced-motion: no-preference) {
  ul {
    transition: transform 0.6s cubic-bezier(.68,-0.55,.27,1.55), visibility 0.3s linear;
  }
}

[aria-expanded="false"] + ul {
  transform: var(--nav-list-transform, translateX(100%));
  visibility: var(--nav-list-visibility, hidden);
}

So wird sichergestellt, dass die Animation nur Nutzern angezeigt wird, die keine reduzierte Bewegung bevorzugen.

Sehen Sie sich Schritt 7: Liste in CodePen animieren an.

Fokus-Styling verbessern

Nutzer mit Tastatur orientieren sich an den Fokusstilen von Elementen, um sich auf einer Seite zurechtzufinden und zu navigieren. Standard-Akzentstile sind besser als gar keine Akzentstile (was passiert, wenn Sie outline: none festlegen). Deutlicher sichtbare benutzerdefinierte Akzentstile verbessern jedoch die Nutzerfreundlichkeit.

So sehen die standardmäßigen Fokusstile für den Link in Chrome 103 aus.

Ein blauer 2-Pixel-Umriss um einen fokussierten Link in Chrome 103

Sie können das verbessern, indem Sie Ihre eigenen Stile in Ihren eigenen Farben bereitstellen. Wenn Sie :focus-visible anstelle von :focus verwenden, entscheidet der Browser, wann Fokusstile angezeigt werden sollen. :focus-Stile sind für alle Nutzer sichtbar, unabhängig davon, ob sie eine Maus, eine Tastatur oder Touchbedienung verwenden und ob sie die Stile benötigen oder nicht. Bei :focus-visible entscheidet der Browser anhand interner Heuristiken, ob sie nur Nutzern mit Tastatur oder allen Nutzern angezeigt werden.

/* Remove the default :focus outline */
*:focus {
  outline: none;
}

/* Show a custom outline on :focus-visible */
*:focus-visible {
  outline: 2px solid var(--color-shades-dark);
  outline-offset: 4px;
}

Browserunterstützung für :focus-visible

Browser Support

  • Chrome: 86.
  • Edge: 86.
  • Firefox: 85.
  • Safari: 15.4.

Source

Deutlich sichtbare dunkle Umrisse mit 2 Pixeln Breite und Abstand im Inneren.

Es gibt verschiedene Möglichkeiten, Elemente hervorzuheben, wenn sie den Fokus haben. Die Verwendung der Eigenschaft outline wird empfohlen, da sie das Layout nicht stört, was bei border passieren kann. Außerdem funktioniert sie gut mit dem Modus mit hohem Kontrast unter Windows. Die Properties background-color oder box-shadow funktionieren nicht gut, da sie bei benutzerdefinierten Kontrasteinstellungen möglicherweise gar nicht angezeigt werden.

Eine Website mit dunklem Hintergrund, auf der der Fokus lila hervorgehoben ist.
Sehen Sie sich Schritt 8: Fokusstile in CodePen verbessern an.

Glückwunsch! Sie haben eine fortlaufend optimierte, semantisch reiche, barrierefreie und für Mobilgeräte optimierte Hauptnavigation erstellt.

Es gibt immer etwas, das verbessert werden kann, z. B.:

Denken Sie daran, dass wir zu Beginn dieses Artikels festgelegt haben, dass die Lösung „weder zu einfach noch zu kompliziert“ sein sollte. Das ist der Punkt, an dem wir jetzt sind. Es ist jedoch möglich, die Navigation zu überladen.

Zwischen Navigationen und Menüs gibt es einen deutlichen Unterschied. Navigationen sind Sammlungen von Links, die die Navigation zu ähnlichen Dokumenten ermöglichen. Menüs enthalten Aktionen, die in einem Dokument ausgeführt werden können. Manchmal überschneiden sich diese Aufgaben. Möglicherweise haben Sie eine Navigation, die auch eine Schaltfläche enthält, über die eine Aktion ausgeführt wird, z. B. das Öffnen eines modalen Fensters. Möglicherweise haben Sie auch ein Menü, bei dem eine Aktion zu einer anderen Seite führt, z. B. zu einer Hilfeseite. In diesem Fall ist es wichtig, dass Sie ARIA-Rollen nicht zusammenführen, sondern den Hauptzweck Ihrer Komponente ermitteln und das Markup und die Rollen entsprechend auswählen.

Das Element <nav> hat die implizite ARIA-Rolle „navigation“, was ausreicht, um zu kommunizieren, dass es sich um ein Navigationselement handelt. Auf Websites werden jedoch häufig auch „menu“, „menubar“ und „menuitem“ verwendet. Da wir diese Begriffe manchmal synonym verwenden, könnte es sinnvoll sein, sie zu kombinieren, um die Nutzung für Screenreader-Nutzer zu verbessern. Bevor wir uns ansehen, warum das in der Regel nicht der Fall ist, sehen wir uns die offizielle Definition dieser Rollen an.

Die Navigationsrolle

Eine Sammlung von Navigationselementen (in der Regel Links), mit denen Sie sich im Dokument oder in ähnlichen Dokumenten bewegen können.

navigation (Rolle) WAI-ARIA 1.1

Die Menürolle

Ein Menü enthält oft eine Liste gängiger Aktionen oder Funktionen, die der Nutzer ausführen kann. Die Rolle „Menü“ ist geeignet, wenn eine Liste von Menüpunkten ähnlich wie ein Menü in einer Desktopanwendung dargestellt wird.

menu (Rolle) WAI-ARIA 1.1

Rolle der Menüleiste

Ein Menü, das normalerweise sichtbar bleibt und in der Regel horizontal dargestellt wird. Mit der Rolle „Menüleiste“ können Sie eine Menüleiste erstellen, die der in Windows-, Mac- und Gnome-Desktopanwendungen ähnelt. Eine Menüleiste dient dazu, eine einheitliche Reihe häufig verwendeter Befehle zu erstellen. Autoren sollten dafür sorgen, dass die Menüleiste ähnlich wie die Menüleiste einer Desktop-Benutzeroberfläche funktioniert.

menubar (Rolle) WAI-ARIA 1.1

Die Rolle „menuitem“

Eine Option in einer Reihe von Auswahlmöglichkeiten in einem Menü oder einer Menüleiste.

menuitem (Rolle) WAI-ARIA 1.1

Die Spezifikation ist hier sehr klar: Verwenden Sie die Navigation, um sich im Dokument oder in ähnlichen Dokumenten zu bewegen, und das Menü nur für eine Liste von Aktionen oder Funktionen, die denen in Desktopanwendungen ähneln. Wenn Sie nicht die nächste Version von Google Docs entwickeln, benötigen Sie wahrscheinlich keine der Menürollen für die Hauptnavigation.

Wann ist ein Menü angebracht?

Menüpunkte dienen in erster Linie nicht der Navigation, sondern der Ausführung von Aktionen. Angenommen, Sie haben eine Liste oder Tabelle mit Daten und Nutzer können für jeden Eintrag in der Liste bestimmte Aktionen ausführen. Sie könnten jeder Zeile eine Schaltfläche hinzufügen und die Aktionen anzeigen, wenn Nutzer auf die Schaltfläche klicken.

<ul>
  <li>
    Product 1

    <button aria-expanded="false" aria-controls="options1">Edit</button>

    <div role="menu" id="options1">
      <button role="menuitem">
        Duplicate
      </button>
      <button role="menuitem">
        Delete
      </button>
      <button role="menuitem">
        Disable
      </button>
    </div>
  </li>
  <li>
    Product 2
    ...
  </li>
</ul>

Auswirkungen der Verwendung von Menürollen

Es ist sehr wichtig, diese Menürollen mit Bedacht zu verwenden, da viel schiefgehen kann.

Für Menüs wird eine bestimmte DOM-Struktur vorausgesetzt. menuitem muss ein direktes untergeordnetes Element von menu sein. Der folgende Code könnte das semantische Verhalten beeinträchtigen:

 <!-- Wrong, don't do this -->
<ul role="menu">
  <li>
    <a href="#" role="menuitem">Item 1</a>
  </li>
</ul>

Erfahrene Nutzer erwarten, dass bestimmte Tastenkombinationen mit Menüs und Menüleisten funktionieren. Gemäß dem ARIA Authoring Practices Guide (APG) umfasst dies:

  • Mit der Eingabetaste und der Leertaste können Sie Menüpunkte auswählen.
  • Mit den Pfeiltasten in alle Richtungen können Sie zwischen den Elementen wechseln.
  • Mit den Tasten Pos1 und Ende können Sie den Fokus auf das erste bzw. letzte Element setzen.
  • a–z, um den Fokus auf das nächste Menüelement mit einem Label zu verschieben, das mit dem eingegebenen Zeichen beginnt.
  • Esc, um das Menü zu schließen.

Wenn ein Screenreader ein Menü erkennt, ändert die Software möglicherweise automatisch den Browsermodus, sodass die oben genannten Tastenkürzel verwendet werden können. Unerfahrene Screenreader-Nutzer können das Menü möglicherweise nicht verwenden, weil sie diese Tastenkombinationen nicht kennen oder nicht wissen, wie sie verwendet werden.

Das gilt auch für Nutzer von Tastaturen, die davon ausgehen, dass sie die Umschalttaste und die Umschalttaste + Tabulatortaste verwenden können.

Beim Erstellen von Menüs und Menüleisten gibt es viel zu beachten. Die Frage, ob sie überhaupt verwendet werden sollten, steht dabei an erster Stelle. Wenn Sie eine typische Website erstellen, benötigen Sie nur das Navigationselement mit einer Liste und Links. Dazu gehören auch Single-Page-Anwendungen (SPA) oder Webanwendungen. Der zugrunde liegende Stack spielt keine Rolle. Verwenden Sie keine Menürollen, es sei denn, Sie entwickeln eine App, die einer Desktopanwendung sehr ähnlich ist.

Zusätzliche Ressourcen

Hero-Image von Mick Haupt