Hauptnavigation für eine Website erstellen

In dieser Anleitung wird beschrieben, wie Sie eine barrierefreie Hauptnavigation für eine Website erstellen. Sie erfahren mehr über semantisches HTML, Barrierefreiheit im Internet und darüber, dass die Verwendung von ARIA-Attributen manchmal mehr schaden als nützen kann.

Manuel Matuzović
Manuel Matuzović

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

Für die meisten Websites sollten Sie etwas erstellen, das weder zu einfach noch zu kompliziert ist.

Ebene für Ebene aufbauen

In dieser Anleitung beginnen Sie mit einer einfachen Einrichtung und fügen Ebene für Ebene Funktionen hinzu, bis Sie genügend Informationen, Stile und Funktionen bereitgestellt haben, um die meisten Nutzer zufriedenzustellen. Dazu nutzen Sie das Prinzip der progressiven Verbesserung. Es besagt, dass Sie mit der grundlegendsten und robustesten Lösung beginnen und nach und nach weitere Funktionen hinzufügen. Wenn eine Ebene aus irgendeinem Grund nicht funktioniert, funktioniert die Navigation trotzdem, da sie auf die darunter liegende Ebene zurückgreift.

Grundstruktur

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

  • HTML

    <a href="/home">Home</a>
    <a href="/about-us">About us</a>
    <a href="/pricing">Pricing</a>
    <a href="/contact">Contact</a>
    
  • CSS

    /* 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);
    }
    
Schritt 1: Einfaches HTML und CSS auf CodePen ansehen

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 möglich, aber es gibt noch Verbesserungspotenzial. Sie können dieses grundlegende Muster um zusätzliche Funktionen und Informationen erweitern, um die Nutzerfreundlichkeit zu verbessern.

Sie haben folgende Möglichkeiten:

  • Aktive Seite hervorheben.
  • Die Anzahl der Elemente wird Screenreader-Nutzern angesagt.
  • Fügen Sie eine Markierung hinzu, damit Nutzer von Screenreadern über eine Tastenkombination direkt auf die Navigation zugreifen können.
  • Blenden Sie die Navigation in schmalen Darstellungsbereichen aus.
  • Fokus-Styling verbessern.

Aktive Seite hervorheben

Wenn Sie die aktive Seite hervorheben möchten, 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, nur visuell vermittelt wird. Ein blinder Screenreader-Nutzer könnte den Unterschied zwischen der aktiven Seite und anderen Seiten nicht erkennen. Glücklicherweise bietet der Standard Accessible Rich Internet Applications (ARIA) 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 verwandter Elemente darstellt. Ein Seiten-Token, das verwendet wird, um einen Link innerhalb einer Reihe von Paginierungslinks anzugeben, wobei der Link visuell so gestaltet ist, 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 beispielsweise „aktuelle Seite, Link, Über uns“ statt 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, sodass die Klasse active-page überflüssig 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);
}
Schritt 2: Aktive Seite auf CodePen hervorheben

Anzahl der Elemente ansagen

Sehende Nutzende können anhand der Navigation erkennen, dass sie nur vier Links enthält. Ein blinder Screenreader-Nutzer kann diese Informationen nicht so schnell erfassen. Möglicherweise müssen sie sich durch die gesamte Liste der Links arbeiten. Das ist bei einer kurzen Liste wie in diesem Beispiel vielleicht kein Problem, aber wenn sie 40 Links enthält, kann diese Aufgabe mühsam sein. Wenn Nutzende von Screenreadern im Voraus wissen, dass die Navigation viele Links enthält, entscheiden sie sich möglicherweise für eine andere, effizientere Art der Navigation, z. B. die Suche auf der Website.
Eine gute Möglichkeit, die Anzahl der Elemente im Voraus zu kommunizieren, besteht darin, jeden Link in ein Listenelement (<li>) zu verpacken, das in einer unsortierten 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 Screenreader-Nutzer die Liste findet, wird von der Software etwas wie „Liste, 4 Elemente“ angesagt.

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

Jetzt müssen Sie den Stil anpassen, damit er wie zuvor aussieht.

/* 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 Screenreader-Nutzer viele Vorteile haben:

  • Sie können die Gesamtzahl der Elemente abrufen, bevor sie mit den Elementen interagieren.
  • Sie können Tastenkombinationen verwenden, um von einem Listenelement zum nächsten zu springen.
  • Sie können Tastenkombinationen verwenden, um von Liste zu Liste zu springen.
  • Der Screenreader sagt möglicherweise den Index des aktuellen Elements an (z. B. „Listenelement, zwei von vier“).

Wenn die Seite ohne CSS dargestellt wird, zeigt die Liste die Links als zusammenhängende Gruppe von Elementen an, anstatt nur als eine Reihe von Links.

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, Listensemantik zu entfernen, wenn eine Liste nicht wie eine Liste aussieht. Je nach Komplexität der Navigation kann dies ein Problem sein oder auch nicht. Einerseits ist die Navigation weiterhin nutzbar und es ist nur VoiceOver in Safari betroffen. VoiceOver mit Chrome oder Firefox sagt die Anzahl der Elemente weiterhin an, ebenso wie andere Screenreader, z. B. NVDA. Andererseits können die semantischen Informationen in manchen 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 sich VoiceOver in Safari wie alle anderen Screenreader verhält, können Sie das Problem umgehen, indem Sie die ARIA-Listenrolle explizit für das <ul> festlegen. Dadurch wird das Verhalten auf den Zustand vor dem Entfernen des Listenstils zurückgesetzt. Optisch sieht die Liste immer noch gleich aus.

<ul role="list">
  <li>
     <a href="/home">Home</a>
  </li>
  ...
</ul>
Schritt 3: Anzahl der Elemente auf CodePen ansagen

Sehenswürdigkeit hinzufügen

Mit wenig Aufwand haben Sie die Website für Nutzer von Screenreadern erheblich verbessert. Es gibt aber 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 gewöhnliche Liste in eine Navigationsliste umwandeln, indem Sie das <ul>-Element in ein <nav>-Element einfügen.

Die Verwendung des <nav>-Elements bietet mehrere Vorteile. Ein Screenreader sagt beispielsweise „Navigation“ an, wenn der Nutzer mit dem Element interagiert, und fügt der Seite eine Markierung hinzu. Orientierungspunkte sind spezielle Bereiche auf der Seite, z. B. <header>, <footer> oder <main>, zu denen ein Screenreader springen kann. Markierungen auf einer Seite können nützlich 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. In NVDA können Sie beispielsweise mit der Taste D von Markierung zu Markierung springen. In VoiceOver können Sie den Rotor verwenden, um alle Markierungen auf der Seite aufzulisten. Drücken Sie dazu VO + U.

Eine Liste mit vier Markierungen: Banner, Navigation, Hauptinhalt, Inhaltsinformationen.
Rotor in VoiceOver, der alle Orientierungspunkte auf einer Seite auflistet.

In dieser Liste sehen Sie vier Orientierungspunkte: Banner ist das <header>-Element, Navigation ist das <nav>-Element, Haupt ist das <main>-Element und Inhaltsinformationen ist das <footer>-Element. Diese Liste sollte nicht zu lang sein. Sie sollten nur kritische Teile Ihrer Benutzeroberfläche als Orientierungspunkte markieren, z. B. die Suche auf der Website, eine lokale Navigation oder eine Paginierung.

Wenn ihr eine websiteweite Navigation, eine lokale Navigation für die Seite und eine Paginierung auf einer einzelnen Seite habt, habt ihr möglicherweise auch drei <nav>-Elemente. Das ist in Ordnung, aber jetzt gibt es drei Navigations-Landmarks, die semantisch alle gleich aussehen. Es ist schwierig, sie voneinander zu unterscheiden, es sei denn, Sie kennen die Struktur der Seite sehr gut.

Bild mit drei Orientierungspunkten, die alle mit „Navigation“ beschriftet sind.
Der Rotor in VoiceOver mit drei Navigationspunkten ohne Label.

Damit sie unterscheidbar sind, sollten Sie sie entweder 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 kurzes Label reicht aus. Fassen Sie sich kurz. Lassen Sie Ausdrücke wie „Navigation“ oder „Menü“ weg, da der Screenreader diese Informationen bereits bereitstellt.

Landmarken
VoiceOver listet die Orientierungspunkte „Banner“, „Hauptnavigation“, „Haupt“, „Seitennavigation“, „Seitennavigation auswählen“ und „Inhaltsinformationen“ auf.
Schritt 4: Orientierungspunkt auf CodePen hinzufügen

Navigation in schmalen Darstellungsbereichen ausblenden

Ich persönlich bin kein großer Fan davon, die Hauptnavigation in schmalen Darstellungsbereichen auszublenden. Wenn die Liste der Links jedoch zu lang wird, lässt sich das nicht vermeiden. In diesem Fall sehen Nutzer anstelle der Liste eine Schaltfläche mit der Bezeichnung „Menü“, ein Hamburger-Symbol oder eine Kombination aus beidem. Durch Klicken auf die Schaltfläche wird die Liste ein- und ausgeblendet. Wenn Sie über grundlegende JavaScript- und CSS-Kenntnisse verfügen, ist das machbar. Sie müssen jedoch einige Dinge in Bezug auf UX und Barrierefreiheit beachten.

  • Sie müssen die Liste so ausblenden, dass sie barrierefrei ist.
  • Die Navigation muss über die Tastatur möglich sein.
  • Die Navigation muss kommunizieren, ob sie sichtbar ist oder nicht.

Burger-Button hinzufügen

Da Sie das Prinzip der progressiven Verbesserung befolgen, möchten Sie sicherstellen, dass Ihre Navigation auch dann noch funktioniert und sinnvoll ist, wenn JavaScript deaktiviert ist.
Als Erstes benötigt Ihre Navigation eine Burger-Schaltfläche. Sie erstellen es in HTML in einem Vorlagenelement, klonen es in JavaScript und fügen es der Navigation hinzu.

Eine Seite mit einem Dreistrich-Menü.
Ergebnis: In schmalen Darstellungsbereichen wird in der Navigation anstelle von Links ein Dreistrich-Menü 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 teilt der Screenreader-Software mit, ob das von der Schaltfläche gesteuerte Element maximiert ist oder nicht.
  2. aria-label gibt dem Button einen sogenannten barrierefreien Namen, eine Textalternative für das Burger-Symbol.
  3. Sie blenden das <svg>-Element mit aria-hidden für Hilfstechnologien aus, da es bereits ein Textlabel hat, das von aria-label bereitgestellt wird.
  4. aria-controls teilt Hilfstechnologien, die das Attribut unterstützen (z. B. JAWS), mit, 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, der eine Tastatur oder einen Screenreader verwendet, nach dem Klicken auf die Schaltfläche die Tabulatortaste drückt, erwartet er, dass das erste Element in der Liste fokussiert wird. Wenn die Schaltfläche nach der Liste kommt, wäre das nicht der Fall.

Als Nächstes setzen Sie das Standard-Styling des Buttons zurück und sorgen dafür, dass er 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: Burger-Button auf 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 Darstellungsbereiche 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 in der oberen Ecke des Darstellungsbereichs.

@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 Eigenschaft (—-nav-list-layout) hinzufügen. Das Layout ist standardmäßig spaltenbasiert und wechselt auf größeren Bildschirmen zu zeilenbasiert.

@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;
}

In schmalen Darstellungsbereichen sollte die Navigation in etwa so aussehen.

Die Seite mit der Navigationsliste und dem Burger-Button.
Sowohl die Schaltfläche „Burger“ als auch die Liste befinden sich in der oberen Ecke des Darstellungsbereichs.

Die Liste benötigt offensichtlich etwas CSS. Wir verschieben es in die obere Ecke, füllen den gesamten Bildschirm vertikal aus und wenden background-color und 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;
}

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

Die Navigationsliste wird geöffnet.

Blenden Sie die Liste aus, sodass sie nur angezeigt wird, wenn der Nutzer einmal auf die Schaltfläche klickt, und wieder ausgeblendet wird, wenn er noch einmal klickt. Es ist wichtig, nur die Liste und nicht die gesamte Navigation auszublenden, da das Ausblenden der Navigation auch das Ausblenden eines wichtigen Orientierungspunkts bedeuten würde.

Zuvor haben Sie dem Button ein Click-Event hinzugefügt, um den Wert des Attributs aria-expanded umzuschalten. Diese Informationen können Sie 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);
}

Es ist wichtig, eine Property-Deklaration wie visibility: hidden oder display: none anstelle von opacity: 0 oder translateX(100%) zu verwenden, um die Liste auszublenden. Diese Eigenschaften sorgen dafür, dass die Links nicht fokussiert werden können, wenn die Navigation ausgeblendet ist. Wenn Sie opacity oder translate verwenden, werden Inhalte visuell entfernt. Die Links sind dann zwar unsichtbar, aber immer noch über die Tastatur zugänglich, was verwirrend und frustrierend sein kann. Wenn Sie visibility oder display verwenden, wird das Element visuell ausgeblendet und ist nicht mehr zugänglich. Es wird also für alle Nutzer ausgeblendet.

Schritt 6: Liste ausblenden

Liste animieren

Wenn Sie sich fragen, warum Sie visibility: hidden; anstelle von display: none; verwenden sollten: Mit können Sie die Sichtbarkeit animieren. Es gibt nur zwei Zustände, hidden und visible, aber Sie können es mit einer anderen Eigenschaft wie transform oder opacity kombinieren, um einen Einblend- oder Einblendeffekt zu erstellen. Das würde mit „display: none“ nicht funktionieren, da das Attribut „display“ nicht animiert werden kann.

Mit den folgenden CSS-Übergängen wird opacity ein- und ausgeblendet.

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 Property transition in eine Medienabfrage vom Typ prefers-reduced-motion einbinden, 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 nur Nutzer, die keine reduzierte Bewegung bevorzugen, die Animation sehen.

Schritt 7: Liste auf CodePen animieren

Fokus-Styling verbessern

Nutzer, die eine Tastatur verwenden, sind auf die Fokusstile von Elementen angewiesen, um sich auf einer Seite zu orientieren und zu navigieren. Standardfokusstile sind besser als keine Fokusstile (was passiert, wenn Sie outline: none festlegen). Deutlich sichtbare benutzerdefinierte Fokusstile verbessern jedoch die Nutzerfreundlichkeit.

So sehen die Standardfokusstile 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 eigene Stile in Ihren eigenen Farben bereitstellen. Wenn Sie :focus-visible anstelle von :focus verwenden, überlassen Sie es dem Browser, zu entscheiden, wann Fokusstile angezeigt werden sollen. :focus-Stile sind für alle sichtbar, unabhängig davon, ob sie Maus, Tastatur oder Touchscreen verwenden und ob sie sie benötigen oder nicht. Bei :focus-visible verwendet der Browser interne Heuristiken, um zu entscheiden, ob sie nur Tastaturnutzern oder allen angezeigt werden sollen.

/* 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

Gut sichtbare dunkle 2 px breite Kontur mit Abstand im Inneren.

Es gibt verschiedene Möglichkeiten, Elemente hervorzuheben, wenn sie fokussiert sind. Die Verwendung des Attributs outline wird empfohlen, da es das Layout nicht beeinträchtigt, was bei border passieren könnte, und es funktioniert gut mit dem Modus für hohen Kontrast unter Windows. Eigenschaften, die nicht gut funktionieren, sind background-color oder box-shadow, da sie mit benutzerdefinierten Kontrasteinstellungen möglicherweise gar nicht angezeigt werden.

Eine Website mit dunklem Hintergrund, auf der der Fokus lila hervorgehoben ist.
Schritt 8: Fokusstile auf CodePen verbessern

Glückwunsch! Sie haben eine semantisch reichhaltige, barrierefreie und für Mobilgeräte optimierte Hauptnavigation mit progressiver Verbesserung erstellt.

Es gibt immer etwas, das verbessert werden kann, zum Beispiel:

Wenn Sie sich an den Anfang dieses Artikels erinnern, in dem es hieß, dass die Lösung „weder zu einfach noch zu kompliziert“ sein sollte, dann sind wir jetzt genau an diesem Punkt. Es ist jedoch möglich, eine Navigation zu überdimensionieren.

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

Das <nav>-Element hat eine implizite ARIA-Rolle für die Navigation, die ausreicht, um zu kommunizieren, dass es sich um ein Navigationselement handelt. Oft werden auf Websites aber auch „menu“, „menubar“ und „menuitem“ verwendet. Da wir diese Begriffe manchmal synonym verwenden, könnte es sinnvoll sein, sie zu kombinieren, um die Nutzerfreundlichkeit für Screenreader-Nutzer zu verbessern. Bevor wir uns ansehen, warum das normalerweise nicht der Fall ist, werfen wir einen Blick auf die offizielle Definition dieser Rollen.

Die Navigationsrolle

Eine Sammlung von Navigationselementen (normalerweise Links) zum Navigieren im Dokument oder in zugehörigen Dokumenten.

navigation (role) WAI-ARIA 1.1

Die Rolle „menu“

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

menu (role) WAI-ARIA 1.1

Die Rolle „menubar“

Eine Darstellung des Menüs, die normalerweise sichtbar bleibt und horizontal präsentiert wird. Die Rolle „menubar“ wird verwendet, um eine Menüleiste zu erstellen, die den Menüleisten in Windows-, Mac- und Gnome-Desktopanwendungen ähnelt. Eine Menüleiste wird verwendet, um eine einheitliche Reihe häufig verwendeter Befehle zu erstellen. Autoren sollten darauf achten, dass die Interaktion mit der Menüleiste der typischen Interaktion mit der Menüleiste in einer grafischen Benutzeroberfläche auf dem Desktop ähnelt.

menubar (role) WAI-ARIA 1.1

Die Rolle „menuitem“

Eine Option in einer Reihe von Auswahlmöglichkeiten, die in einem Menü oder einer Menüleiste enthalten sind.

menuitem (role) WAI-ARIA 1.1

Die Spezifikation ist hier sehr klar: Verwenden Sie „navigation“ für die Navigation im Dokument oder in zugehörigen Dokumenten und „menu“ nur für eine Liste von Aktionen oder Funktionen, ähnlich wie Menüs in Desktopanwendungen. Wenn Sie nicht gerade das nächste Google Docs entwickeln, benötigen Sie wahrscheinlich keine der Menürollen für die Hauptnavigation.

Wann ist ein Menü angemessen?

Menüpunkte werden hauptsächlich nicht für die Navigation, sondern zum Ausführen von Aktionen verwendet. Angenommen, Sie haben eine Liste oder Tabelle mit Daten und Nutzer können bestimmte Aktionen für jedes Element in der Liste ausführen. Sie könnten jeder Zeile eine Schaltfläche hinzufügen und die Aktionen anzeigen, wenn die 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.

Menüs erwarten eine bestimmte DOM-Struktur. menuitem muss ein direkt 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 Folgendes:

  • Eingabetaste und Leertaste, um Menüpunkte auszuwählen.
  • Pfeiltasten in alle Richtungen, um zwischen Elementen zu wechseln.
  • Mit den Tasten Pos1 und Ende können Sie den Fokus auf das erste bzw. letzte Element verschieben.
  • a–z, um den Fokus auf den nächsten Menüpunkt zu verschieben, dessen Label 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 zuvor erwähnten Tastenkombinationen verwendet werden können. Unerfahrene Screenreader-Nutzer können das Menü möglicherweise nicht verwenden, weil sie diese Tastenkombinationen oder deren Verwendung nicht kennen.

Das gilt auch für Tastaturnutzer, die erwarten, dass sie die Umschalttaste und die Umschalttaste + Tabulatortaste verwenden können.

Beim Erstellen von Menüs und Menüleisten gibt es viel zu beachten. Am wichtigsten ist die Frage, ob es überhaupt sinnvoll ist, sie zu verwenden. Wenn Sie eine typische Website erstellen, benötigen Sie nur das nav-Element mit einer Liste und Links. Dazu gehören auch Single-Page-Anwendungen (SPA) oder Web-Apps. Der zugrunde liegende Stack spielt keine Rolle. Vermeiden Sie Menürollen, es sei denn, Sie erstellen etwas, das einer Desktopanwendung sehr nahe kommt.

Zusätzliche Ressourcen