Kapitel 4. Aktionen durchführen

Diese Arbeit wurde mithilfe von KI übersetzt. Wir freuen uns über dein Feedback und deine Kommentare: translation-feedback@oreilly.com

Dieses ganze Kapitel konzentriert sich auf ein einziges HTML-Element, das <button>. Es gibt zwei Gründe, warum ich Schaltflächen so viel Platz einräume.

Erstens ist die Schaltfläche ein gängiges Element, das du auf den meisten Seiten findest: in einem Kontakt- oder Newsletter-Anmeldeformular, zum Umschalten einer mobilen Navigation oder zum Schließen eines Pop-up-Dialogs.

Zweitens: Obwohl Webentwickler so oft Buttons brauchen, sind sie schlecht darin, sie richtig zu implementieren. Das beruht nicht nur auf meiner jahrelangen Erfahrung bei der Überprüfung von Websites, die andere erstellt haben.

Deshalb konzentriert sich dieses Kapitel auf die wichtigsten Anforderungen an das Button-Element und wie man sie erfüllt.

4.1 Wähle das richtige Element

Problem

Wenn eine Schaltfläche nicht den grundlegenden Anforderungen entspricht, kann es sein, dass du eine oder mehrere Gruppen von Nutzern davon ausschließt, auf sie zuzugreifen oder ihren Zweck zu verstehen.

Der Diskussionsteil dieses Rezepts enthält weitere Details, aber die wichtigsten Kriterien für die Zugänglichkeit einer Schaltfläche sind:

  • Sie muss ihre semantische Tastenfunktion programmatisch vermitteln.

  • Sie hat einen prägnanten und leicht verständlichen Namen (sichtbarer Text oder eine Textalternative).

  • Sie teilt ihren Zustand mit (gedrückt, erweitert usw.), falls nötig.

  • Er ist als Knopf zu erkennen.

  • Die Farben müssen genügend Kontrast haben.

  • Sie muss fokussierbar sein und die Aktivierung durch Klick-, Touch- und Tastenereignisse ermöglichen.

Lösung

Verwende das native Schaltflächenelement und die HTML- und ARIA-Attribute, um seine Funktionen den Anforderungen entsprechend anzupassen, wie in den Beispielen 4-1, 4-2 und 4-3 gezeigt.

Beispiel 4-1. Ein nativer Submit-Button, der in einem Formular zum Übermitteln von Daten verwendet wird
<form>
  <label for="email">Email address</label>
  <input type="email" id="email" name="email">

  <button>Sign up</button>
</form>
Beispiel 4-2. Eine Schaltfläche, die JavaScript ausführt
<button type="button" onclick="print()">
  Print
</button>
Beispiel 4-3. Eine Schaltfläche, die ihren gedrückten Zustand mitteilt
<button type="button" aria-pressed="true">
  Mute
</button>

Diskussion

Das Button-Element hat zwei Hauptanwendungsfälle: das Absenden eines Formulars und das Ausführen von JavaScript, wenn ein Nutzer damit interagiert.

Eine Schaltfläche wird zu einer Submit-Schaltfläche, wenn du ihren Typ auf Submit oder im Kontext eines Formulars setzt, wie in Beispiel 4-1 gezeigt. Normalerweise verwendest du einen Submit-Button, um Formulardaten an einen Server zu senden.

Wenn du den Typ auf Schaltfläche setzt, tut die Schaltfläche nichts. Das machst du, wenn du JavaScript ausführen willst, wenn der Benutzer die Schaltfläche aktiviert. Wenn du zum Beispiel auf die Schaltfläche in Beispiel 4-2 klickst, wird der Druckdialog deines Browsers geöffnet. Andere häufige Anwendungen sind das Umschalten der Sichtbarkeit anderer Elemente (siehe Kapitel 8), das Öffnen von modalen Dialogen (siehe Rezept 11.3) und das Ausführen anderer JavaScript-Funktionen.

Laut der WCAG muss eine Schaltfläche mindestens sechs spezifische Anforderungen erfüllen, um barrierefrei zu sein und eine gute UX zu bieten. Schauen wir uns jede einzelne Anforderung an:

Es muss seine semantische Button-Rolle programmatisch vermitteln.

Deine Schaltflächen müssen ihre semantischen Rollen vermitteln. Die sicherste und zuverlässigste Option ist die Verwendung des Elements <button>, da es eine implizite button Rolle hat.

Ein Bildschirmlesegerät sagt die Funktion der Schaltfläche neben ihrem Namen an, zum Beispiel "Drucken, Schaltfläche".

Sie hat einen zugänglichen Namen (sichtbarer Text oder eine Textalternative).

Unabhängig davon, ob eine Schaltfläche Text enthält, muss sie einen zugänglichen Namen haben. Es gibt keine Ausnahmen von dieser Regel. Wenn du die Schaltflächen nicht beschriftest, wissen Screenreader- und Sprachbenutzer nicht, was sie mit ihnen machen sollen.

Es gibt verschiedene Möglichkeiten, Schaltflächen zu beschriften. Rezept 4.2 beschreibt einige davon, aber in den meisten Fällen ist es am besten, wenn du Text einfügst, der für alle sichtbar ist.

Er teilt seinen Zustand (gedrückt, erweitert, etc.) mit, wenn nötig.

Eine Schaltfläche kann verschiedene Zustände haben oder den Zustand eines anderen Elements steuern: Wenn das der Fall ist, muss sie ihren Zustand oder ihre Beziehung mit ARIA-Attributen vermitteln. Die Schaltfläche in Beispiel 4-3 zeigt an, dass bestimmte Medien stummgeschaltet sind. Weitere Beispiele findest du in Rezept 4.5.

Er ist als Knopf zu erkennen.

Laut verbringt der Nutzer von die meiste Zeit auf anderen Websites. Das bedeutet, dass die Nutzer es vorziehen, dass deine Website genauso funktioniert wie alle anderen Websites, die sie bereits kennen. Für Schaltflächen bedeutet das, dass sie den visuellen Erwartungen der Nutzer/innen an eine Schaltfläche entsprechen sollten. Wenn eine Schaltfläche wie eine Schaltfläche aussieht, ist es für Nutzer/innen, insbesondere für Menschen mit kognitiven Einschränkungen, einfacher, ihren Zweck zu verstehen. Das gilt auch für den zugänglichen Namen. Wenn identische Funktionen auf verschiedenen Seiten unterschiedliche barrierefreie Namen haben, wird die Nutzung der Website erschwert.

Die Farben müssen genügend Kontrast haben.

Genau wie die meisten Texte oder Textbilder auf einer Webseite müssen auch Schaltflächen Mindestkontrastanforderungen erfüllen. Die Textfarbe in einem Button muss ein Kontrastverhältnis von mindestens 4,5:1 für normalen Text oder 3:1 für großen oder fetten Text haben.

Andere Farben, die in der Schaltfläche verwendet werden, wie die Hintergrundfarbe oder die Farben der Fokusindikatoren, sollten ebenfalls die Anforderungen an das Mindestkontrastverhältnis zu benachbarten Farben erfüllen. Mit anderen Worten: Die Hintergrundfarbe der Schaltfläche oder der Umriss eines Fokusindikators oder Rahmens sollte ebenfalls ein Kontrastverhältnis von mindestens 3:1 zum Hintergrund haben, der normalerweise eine übergeordnete Komponente oder die Seite selbst ist. Kontrastarme Bedienelemente sind schwieriger zu erkennen und können von Menschen mit Sehschwäche komplett übersehen werden.

muss über Tabs erreichbar sein und die Aktivierung über Klick-, Touch- und Tastenereignisse ermöglichen.

Eine Schaltfläche ist ein interaktives Element, d.h. wenn du sie anklicken kannst, musst du die gleiche Aktion auch über die Tastatur ausführen können, indem du Enter oder Space drückst. Dazu muss sie tabbable sein (erreichbar über die Taste Tab ), was beim Element <button> standardmäßig der Fall ist.

Die meisten Websites enthalten Schaltflächen. Halte dich an die bewährten Methoden in diesem Kapitel und vermeide einige gängige Alternativlösungen, die die in Beispiel 4-4 aufgeführten Anforderungen nicht erfüllen. Es ist möglich, die Standardfunktionalität der nativen Schaltfläche mit einem anderen Element wie <div> nachzubilden, aber in der Regel lohnt sich der Aufwand nicht, da <button> die meisten der in diesem Rezept beschriebenen Funktionen bereits enthält.

Beispiel 4-4. Schlechte Praktiken: Häufige unzugängliche Button-Alternativen, die du vermeiden solltest
<!-- Div with a click event -->
<div onclick="[JS function]">
  O'Reilly books and videos
</div>

<!-- Non-focusable button -->
<div role="button" onclick="[JS function]">
  O'Reilly books and videos
</div>

<!-- Link with a click event -->
<a href="javascript: void(0)" onclick="[JS function]">
  Menu
</a>

<!-- Link with a click event -->
<a href="#" onclick="[JS function]">
  Menu
</a>

4.2 Beschriften Sie die Schaltflächen deutlich

Problem

Schaltflächen können verschiedene Formen und Ausprägungen haben. Der in der Schaltfläche enthaltene Inhalt kann Text, ein Symbol oder beides sein. Wenn du eine Schaltfläche nicht benennst, unabhängig davon, ob das Design dies vorsieht, können Screenreader-Nutzer ihren Zweck möglicherweise nicht erkennen.

Lösung

Wenn die Schaltfläche Text enthält, dient dieser Text als Beschriftung, wie in Beispiel 4-5 gezeigt.

Beispiel 4-5. Schaltfläche mit dem zugänglichen Namen, der sich aus ihrem Inhalt ergibt
<button type="button">
  Download
</button>

Zweitens: Wenn die Schaltfläche ein Bild enthält, sollte das alt Attribut des Bildes die Bezeichnung enthalten, wie in Beispiel 4-6.

Beispiel 4-6. Schaltfläche mit dem zugänglichen Namen, der aus dem alt Attribut des Bildes stammt
<button type="button">
  <img src="/images/download.svg" alt="Download" width="26">
</button>

Anstelle von img kannst du auch in einem SVG mit einem <title> Element verwenden. Für eine browserübergreifende Unterstützung verwendest du aria-labelledby für die SVG und erstellst einen Verweis auf den Titel, wie in Beispiel 4-7 gezeigt.

Beispiel 4-7. Schaltfläche mit dem zugänglichen Namen aus dem SVG
<button type="button">
  <svg viewBox="0 0 39 44" aria-labelledby="title" role="img" width="26">
    <title id="title">Download</title>
    <path d="M19.5 36.5 1.6 26.1v-3.6l16.3 9.4V1.5h3.2v30.4l16.3-9.4v3.6z"/>
    <path d="M1 41.5h37" style="stroke:#000;stroke-width:3;"/>
  </svg>
</button>

Du kannst die Grafik auch aus dem Zugänglichkeitsbaum entfernen, indem du ein leeres alt Attribut auf img oder aria-hidden="true" in der SVG definierst. Wenn du das tust, braucht die Schaltfläche immer noch eine Textalternative, die du mit visuell verborgenem Text (siehe Beispiel 4-8), aria-labelledby oder aria-label (siehe Beispiel 4-9) bereitstellen kannst.

Beispiel 4-8. Der visuell verborgene Text beschriftet die Schaltfläche
<button type="button">
  <span class="visually-hidden">Download</span>
  <img src="/images/download.svg" alt="" width="26">
</button>

<!-- or -->

<button type="button">
  <span class="visually-hidden">Download</span>
  <svg viewBox="0 0 39 44" aria-hidden="true" width="26">
    <path d="M19.5 36.5 1.6 26.1v-3.6l16.3 9.4V1.5h3.2v30.4l16.3-9.4v3.6z"/>
    <path d="M1 41.5h37" style="stroke:#000;stroke-width:3;"/>
  </svg>
</button>

<style>
  .visually-hidden {
    clip-path: inset(50%);
    height: 1px;
    overflow: hidden;
    position: absolute;
    white-space: nowrap;
    width: 1px;
  }
</style>
Beispiel 4-9. Das Attribut aria-label beschriftet die Schaltfläche
<button type="button" aria-label="Save">
  <svg aria-hidden="true" viewBox="0 0 39 44" width="26">
    <path d="M19.5 36.5 1.6 26.1v-3.6l16.3 9.4V1.5h3.2v30.4l16.3-9.4v3.6z"/>
    <path d="M1 41.5h37" style="stroke:#000;stroke-width:3;"/>
  </svg>
</button>

Das Entfernen von verschachtelten Grafiken aus dem Zugänglichkeitsbaum ist auch hilfreich, wenn du ein Symbol mit Text kombinierst, weil der Text eine zusätzliche Beschriftung für das Symbol überflüssig macht, wie in Beispiel 4-10 gezeigt.

Beispiel 4-10. Kombination aus Text und Symbol
<button type="button">
  Save
  <img src="/images/download.svg" alt="" width="26">
</button>

<button type="button">
  Save
  <svg aria-hidden="true" viewBox="0 0 39 44" width="26">
    <path d="M19.5 36.5 1.6 26.1v-3.6l16.3 9.4V1.5h3.2v30.4l16.3-9.4v3.6z"/>
    <path d="M1 41.5h37" style="stroke:#000;stroke-width:3;"/>
  </svg>
</button>

Diskussion

Laut enthielten 28,2 % der getesteten Websites leere Schaltflächen ( ). Der Bericht WebAIM Million 2024 ist das Ergebnis einer jährlichen automatisierten Bewertung der wichtigsten 1 Million Websites im Bereich Barrierefreiheit. Eine leere Schaltfläche ist entweder eine Schaltfläche ohne untergeordnete Elemente oder eine Schaltfläche, die nicht beschriftete Grafiken enthält und keine andere Quelle hat, die sie beschriftet.

Es gibt verschiedene Methoden zur Beschriftung von Buttons. Welche du wählst, hängt von deinen Anforderungen ab. Wenn du mehrere Möglichkeiten hast, empfehle ich dir, der Prioritätsreihenfolge zu folgen, die Adrian Roselli in "Meine Priorität der Methoden zur Kennzeichnung einer Kontrolle" beschreibt :

  1. Native HTML-Techniken

  2. aria-labelledby Zeigen auf vorhandenen sichtbaren Text

  3. Sichtbar versteckter Inhalt

  4. aria-label

Wenn die Schaltfläche nur Text oder eine Kombination aus Text und Symbolen enthält, füge die Beschriftung als Text zwischen dem Start- und End-Tag des Elements ein, wie in Beispiel 4-5 gezeigt. Wenn es ein Symbol gibt, das keine zusätzlichen Informationen liefert, entferne es aus dem Zugänglichkeitsbaum, um Redundanz zu vermeiden (siehe Beispiel 4-10).

Wenn es keinen sichtbaren Text gibt, sondern nur ein Bild oder ein Symbol, dann kann der alternative Text als Name für die Schaltfläche dienen (siehe Beispiele 4-6 und 4-7). Diese Art von Bildern werden Funktionsbilder genannt. Ihr alternativer Text sollte nicht beschreiben, was sie zeigen, sondern ihren Zweck. Alternativ kannst du visuell versteckten Text(Beispiel 4-8), aria-labelledby oder das Attribut aria-label (Beispiel 4-9) verwenden.

Fehlende barrierefreie Namen sind wahrscheinlich das häufigste Problem, aber auch falsche Namen können problematisch sein. Manchmal sind sie in der falschen natürlichen Sprache, wie Englisch auf einer französischen Website. Manchmal enthalten sie nicht aufgelöste Variablen oder Platzhaltertext. Diese Probleme treten meist bei Schaltflächen auf, die nur Symbole enthalten. Visuell versteckter Text oder Beschriftungen, die über Attribute wie aria-label bereitgestellt werden, können leicht übersehen werden, da sie nur im Code und nicht in der gerenderten Benutzeroberfläche sichtbar sind. Du solltest Schaltflächen mit sichtbarem Text bevorzugen, denn sie sind allgemein verständlich und weniger fehleranfällig.

Die Beschriftung sollte informativ und prägnant sein. Beschrifte eine Schaltfläche nicht mit "Klicken Sie hier, um die Navigation zu öffnen oder zu schließen." "Navigation" ist ausreichend.

4.3 Standard-Schaltflächenstile entfernen

Problem

Auch wenn eine Schaltfläche nicht wie eine Schaltfläche aussieht, muss sie dennoch die meisten der in Rezept 4.1 beschriebenen Anforderungen erfüllen. Ist dies nicht der Fall, kann es sein, dass sie für Tastatur- und Screenreader-Nutzer nicht zugänglich ist. Wenn du anstelle des <button> Elements ein generisches Element mit weniger Standardstilen auswählst, können die Benutzer möglicherweise nicht auf die gefälschte Schaltfläche zugreifen oder ihren Zweck nicht verstehen.

Lösung

Wenn du eine Schaltfläche verwenden, sie aber nicht wie eine Schaltfläche aussehen lassen willst, solltest du das Element <button> verwenden, aber die Standard-Schaltflächenstile entfernen. CSS bietet drei effiziente Strategien zum Entfernen der Standard-Schaltflächenstile, wie in den Beispielen 4-11, 4-12 und 4-13 gezeigt.

Beispiel 4-11. Eigenschaften manuell entfernen oder zurücksetzen
button {
  background: none;
  border: 0.1em solid transparent; 1
  font: inherit;
  padding: 0;
}
1

Zeigt einen Umriss im Modus "Erzwungene Farben" an, was hilfreich sein kann.

Beispiel 4-12. Zurücksetzen aller Schaltflächeneigenschaften auf ihren Anfangswert
button {
  all: initial;
}

button:focus-visible {
  outline: 0.1em solid;
  outline-offset: 0.1em;
}
Beispiel 4-13. Zurücksetzen aller Schaltflächeneigenschaften auf ihren ursprünglichen Wert, mit Ausnahme der vererbbaren Eigenschaften
button {
  all: unset;
}

button:focus-visible {
  outline: 0.1em solid;
  outline-offset: 0.1em;
}

Diskussion

Schaltflächen in Betriebssystemen und Webseiten haben eine bestimmte Standardform und -gestaltung: ein Rechteck mit einem Rahmen, einer Hintergrundfarbe und etwas Füllung zwischen dem Text und dem Rahmen. Wenn du eine Seite gestaltest, hältst du dich normalerweise an diese Standardmerkmale. Du änderst die Standardwerte und fügst vielleicht Eigenschaften hinzu, wie in Beispiel 4-14 gezeigt. Du könntest auch Versionen dieser Schaltfläche haben, die sich in Größe, Farbe und Form unterscheiden.

Beispiel 4-14. Benutzerdefinierte Stile für Schaltflächen
button {
  --_l: 0.47;

  background: oklch(var(--_l) 0.05 195.6);
  color: #fff;
  font-size: 1.2rem;
  font-family: inherit;
  padding: 0.4em 0.9em;
  border-radius: 3px;
  border: 0;
  min-inline-size: 7rem;
}

button:is(:hover, :focus-visible) {
  --_l: 0.27; 1
}
1

Die Hintergrundfarbe wird auf hover und focus-visible dunkler.

Manche Schaltflächen sehen nicht wie Schaltflächen aus, weil sie nur aus einem Symbol bestehen. Wie du eine solche Schaltfläche implementierst, ist entscheidend. Eines der häufigsten Probleme mit der Barrierefreiheit auf den meisten Websites, die ich überprüfe, sind unechte Schaltflächen: Viele Entwickler gehen davon aus, dass eine Schaltfläche, die nicht wie eine Schaltfläche aussieht, auch kein <button> Element sein muss. Ihre Argumentation lautet: Wenn es erst einmal keine Schaltflächenstile gibt, muss man sie auch nicht entfernen. Das führt oft zu Code wie dem in Beispiel 4-15, der harmlos aussieht, aber die Barrierefreiheit erheblich beeinträchtigt.

Beispiel 4-15. Schlechte Praxis: Ein gefälschter div Button
<div class="button" aria-label="Navigation">
  <svg width="24" height="24" aria-hidden="true">
    <path d="M3 18h18v-2H3v2zm0-5h18v-2H3v2zm0-7v2h18V6H3z">
  </svg>
</div>

<script>
const button = document.querySelector(".button");
button.addEventListener("click", (e) => {
  console.log("do something");
});
</script>

Es gibt mehrere Probleme mit diesem "Button":.

  • Es ist nicht über die Tastatur fokussierbar.

  • Selbst wenn sie fokussierbar wäre, würde die Aktivierung über Enter oder Space nicht funktionieren.

  • Bildschirmleser zeigen sie nicht als Schaltfläche an.

  • Manche Bildschirmlesegeräte zeigen sie gar nicht an.

  • Du solltest aria-label nicht für generische Elemente verwenden, weil es ungültig ist, sie zu benennen.

Dass diese "Schaltfläche" nicht fokussierbar ist, wirkt sich auf Tastatur- und Screenreadernutzer aus, aber letztere können den virtuellen Cursor verwenden, um auf die falsche Schaltfläche zuzugreifen. Wenn ein Klick-Ereignis-Listener an die div angehängt ist, weisen einige Screenreader darauf hin, dass man sie anklicken kann. Wenn du dir jedoch Tabelle 4-1 ansiehst, siehst du, dass die Verwendung eines div oder eines anderen nicht interaktiven Elements nicht zuverlässig ist. Wenn du die Standardstile für Schaltflächen entfernen musst, ist es am sichersten, wenn du das <button> Element verwendest und die Stile mit CSS zurücksetzt.

Tabelle 4-1. Screenreader-Test: Zugänglichkeit einer Schaltfläche div
Bildschirmleser Browser Bildschirmleser-Erzählung

NVDA

Firefox

Navigation

JAWS

Chrom

N/A

Erzähler

Kanten

N/A

TalkBack

Chrom

Navigation

VoiceOver macOS

Safari

Navigation, leere Gruppe

VoiceOver iOS

Safari

N/A

Es wäre nicht praktikabel, ein generisches Element anstelle einer Schaltfläche zu verwenden oder Ereignis-Listener auf nicht interaktive Elemente zu setzen. Du brauchst ein interaktives Element, wenn der Benutzer mit einer Komponente interagieren kann.

Die vier CSS-Zeilen, die du in Beispiel 4-11 siehst, sind alles, was du brauchst, um die Standard-Benutzeragentenstile der Schaltflächen zu entfernen - vorausgesetzt, du hast nicht noch weitere Regeln hinzugefügt, wie wir es in Beispiel 4-14 getan haben. In diesem Fall müsstest du auch diese Stile zurücksetzen. Das ist das Problem bei diesem manuellen Ansatz: Du musst die Änderungen an deinen benutzerdefinierten Standardstilen im Auge behalten und die zurückgesetzten Stile entsprechend anpassen, oder du musst alle möglichen Eigenschaften im Voraus zurücksetzen.

Die in den Beispielen 4-12 und 4-13 gezeigte Vorgehensweise ist viel effizienter. Mit der Eigenschaft all in CSS kannst du alle Eigenschaften eines Elements zurücksetzen, außer unicode-bidi, direction und CSS Custom Properties. Je nach deinem Bedarf kannst du den Wert auf initial oder unset setzen (siehe Abbildung 4-1).

The button looks like regular text written in a serif font.
Abbildung 4-1. Eine Schaltfläche mit Standard-Styling, eine Schaltfläche, bei der alle Eigenschaften auf initial eingestellt sind, und eine Schaltfläche, bei der alle Eigenschaften auf unset

Das Schlüsselwort initial setzt alle Eigenschaftswerte auf ihren Anfangswert. Jede Eigenschaft hat einen Anfangswert, der in der Definitionstabelle der Eigenschaft festgelegt ist. Wenn du dir zum Beispiel die Eigenschaft color in der Spezifikation ansiehst, lautet der definierte Anfangswert in der Definitionstabelle CanvasText. Beachte, dass der Anfangswert nicht der Standardwert der Eigenschaft ist, der im User Agent definiert ist.

Das Schlüsselwort unset setzt eine Eigenschaft auf ihren geerbten Wert zurück, wenn die Eigenschaft natürlich von ihrem Elternteil geerbt hat, und auf ihren ursprünglichen Wert, wenn nicht. Das kann nützlich sein, wenn du bestimmte Eigenschaften wie font-family oder color behalten willst.

In jedem Fall musst du die Stile focus und hover zurückbringen, da all auch diese zurücksetzt. Das Wichtigste ist, dass sich eine Schaltfläche, auch wenn sie nicht wie eine Schaltfläche aussieht, wie eine Schaltfläche verhalten muss .

4.4 Zustände und Eigenschaften hinzufügen

Problem

Wenn Benutzer von Bildschirmlesern Schaltflächen verwenden, um andere Elemente auf der Seite oder Einstellungen für die Website zu steuern, müssen diese Schaltflächen so viele Informationen wie möglich enthalten. Dazu gehören z. B. die Art der Schaltfläche, die Art des zugehörigen Elements oder der Status einer Schaltfläche oder eines gesteuerten Elements. Wenn diese Informationen fehlen, ist es viel komplizierter - oder manchmal sogar unmöglich - festzustellen, ob der Nutzer die Schaltfläche erfolgreich aktiviert hat und was passiert, wenn er dies tut.

Lösung

Eine Schaltfläche, die die Sichtbarkeit eines anderen Elements umschaltet, muss mitteilen, ob das Element erweitert ist, wie in Beispiel 4-16 zeigt.

Beispiel 4-16. Das Attribut aria-expanded auf der Schaltfläche teilt mit, ob die Navigation sichtbar ist
<nav>
  <button aria-expanded="false" aria-controls="main_nav"> 1
    Navigation
  </button>

  <ul id="main_nav"></ul>
</nav>

<style>
  [aria-expanded="false"] + ul { 2
    display: none;
  }
</style>

<script>
const button = document.querySelector("button");

button.addEventListener("click", (e) => {  3
  const isExpanded = button.getAttribute("aria-expanded") === "true";
  button.setAttribute("aria-expanded", !isExpanded);
});
</script>
1

aria-expanded muss sich auf der Schaltfläche befinden und nicht auf dem erweiterbaren Element.

2

Die Liste wird ausgeblendet, je nach Wert des Attributs.

3

Wenn du auf die Schaltfläche klickst, wird der Wert des Attributs aria-expanded umgeschaltet.

Eine Schaltfläche, die eine Einstellung ein- oder ausschaltet, muss mitteilen, ob sie aktiv ist, wie in Beispiel 4-17 gezeigt.

Beispiel 4-17. Eine Schaltfläche, die ihren gedrückten Zustand mitteilt
<button type="button" aria-pressed="true"> 1
  Add to favourites
</button>

<script>
const button = document.querySelector("button");

button.addEventListener("click", (e) => {
  const isPressed = button.getAttribute("aria-pressed") === "true";
  button.setAttribute("aria-pressed", !isPressed);
});
</script>
1

Die Schaltfläche zeigt an, dass etwas als Favorit hinzugefügt wurde.

Eine Schaltfläche, die eine Einstellung umschaltet, muss mitteilen, ob sie aktiv ist. Abbildung 4-2 und Beispiel 4-18 zeigen eine Schaltfläche, die ihren Zustand über das Attribut aria-checked mitteilt.

A green button with rounded corners. A white circle inside it, aligned to the right indicating is switched on. Text 'functional cookies' outside, on the right of the button.
Abbildung 4-2. Ein Kippschalter
Beispiel 4-18. Ein Schaltknopf
<button role="switch" aria-checked="false">Functional cookies</button>

<script>
const button = document.querySelector("button");

button.addEventListener("click", (e) => {
  const isChecked = button.getAttribute("aria-checked") === "true";
  button.setAttribute("aria-checked", !isChecked);
});
</script>

<style>
  button {
    --toggle-offset: 0.125em;
    --toggle-height: 1.6em;
    --toggle-background: oklab(0.82 0 0);

    all: unset; 1
    align-items: center;
    display: flex;
    gap: 0.5em;
    position: relative;
  }

  button::before { 2
    background: var(--toggle-background);
    border-radius: 4em;
    content: "";
    display: inline-block;
    height: var(--toggle-height);
    transition: background 0.3s, box-shadow 0.3s;
    width: 3em;
  }

  button::after { 3
    --_size: calc(var(--toggle-height) - (var(--toggle-offset) * 2));

    background: #FFF;
    border-radius: 50%;
    content: "";
    height: var(--_size);
    left: var(--toggle-offset);
    position: absolute;
    transition: translate 0.3s;
    top: var(--toggle-offset);
    width: var(--_size);
  }

  button:focus-visible::before { 4
    outline: 2px solid;
    outline-offset: 2px;
  }

  button:is(:focus-visible, :hover)::before {  5
    box-shadow: 0px 0px 3px 1px rgb(0 0 0 / 0.3);
  }

  [aria-checked="true"] { 6
    --toggle-background: oklab(0.7 -0.18 0.17);
  }

  button[aria-checked="true"]::after {  7
    translate: 100% 0;
  }
</style>
1

Setzt die Standard-Schaltflächenstile zurück.

2

Pseudoelement für den Hintergrund des Schalters.

3

Pseudoelement für den beweglichen Indikator des Schalters.

4

Fügt benutzerdefinierte Fokusstile hinzu.

5

Zeigt einen Kastenschatten auf :hover und :focus-visible.

6

Schaltet die Hintergrundfarbe des Schalters auf grün, wenn er aktiv ist.

7

Bewegt den Indikator an das Ende des Schalters, wenn er aktiv ist.

Eine Schaltfläche kann ihren Zustand und die Art des Elements, das sie steuert, mitteilen, wie in Beispiel 4-19 gezeigt.

Beispiel 4-19. Eine Schaltfläche, die ein Menü steuert
<button
  type="button"
  aria-haspopup="menu" 1
  aria-expanded="false" 2
  id="button_settings"
>
  Settings
</button>

<ul role="menu" aria-labelledby="button_settings" hidden> 3
  <li role="none">
    <button role="menuitem">Print</button>
  </li>
  <li role="none">
    <button role="menuitem">Save</button>
  </li>
</ul>

<style>
  [aria-expanded="true"] + ul { 4
    display: block;
  }
</style>

<script>
const button = document.querySelector("button");

button.addEventListener("click", (e) => { 5
  const isExpanded = button.getAttribute("aria-expanded") === "true";
  button.setAttribute("aria-expanded", !isExpanded);
});
</script>
1

Zeigt an, dass die Schaltfläche ein Menü steuert.

2

Zeigt an, dass das kontrollierte Menü eingeklappt ist.

3

Das Menü ist standardmäßig ausgeblendet.

4

Die Liste wird ausgeblendet, je nach Wert des Attributs.

5

Wenn du auf die Schaltfläche klickst, wird der Wert des Attributs aria-expanded umgeschaltet.

Diskussion

Viele Attribute in der ARIA-Spezifikation statten Elemente mit Zuständen oder Eigenschaften aus. Wenn du benutzerdefinierte JavaScript-Widgets erstellst, wirst du einige von ihnen häufig verwenden. Die Eigenschaft arial-label zum Beispiel gibt einem Element einen zugänglichen Namen, während der Status aria-hidden ein Element aus dem Zugänglichkeitsbaum entfernt.

Dieses Rezept konzentriert sich auf vier Attribute, die häufig bei Schaltflächen verwendet werden.

Der erweiterte Staat

Du das aria-expanded Attribut auf einem Schaltflächenelement, um anzugeben, ob ein Gruppierungselement, das es steuert, erweitert oder eingeklappt ist.

Hinweis

Das kontrollierte Element kann so ziemlich jedes Element sein, aber normalerweise ist es ein Gruppierungselement wie <div>, <p> oder <ul>.

In Beispiel 4-16 kannst du sehen, dass die Schaltfläche das Attribut hat und mitteilt, dass das zugehörige Element erweitert ist. Die Nutzer sollten aus dem Text der Schaltfläche erkennen können, welches Element die Schaltfläche steuert. Deshalb solltest du generischen Text wie "ein-/ausblenden" vermeiden. Das Attribut kann für Fly-in-Navigationen (siehe Rezept 7.5), für Untermenüs in verschachtelten Navigationen (siehe Rezept 7.7) und für Disclosure Widgets (siehe Rezept 8.3) nützlich sein.

Die Schaltfläche hat die Aufgabe, mitzuteilen, ob das kontrollierte Element erweitert ist. Du musst drei wichtige Regeln beachten, wenn du sie anwendest:

  • Du setzt das Attribut auf das Element, das die Kontrolle ausübt (die Schaltfläche), nicht auf das kontrollierte Element (die Gruppe).

  • Das bloße Vorhandensein des Attributs reicht nicht aus; du musst es auf "wahr" oder "falsch" setzen.

  • Das Attribut muss vorhanden und gesetzt sein, bevor der Nutzer mit der Schaltfläche interagiert. Wenn du den Wert auf "false" setzt, bedeutet das, dass das kontrollierte Element zugeklappt ist. Wenn du das Attribut nicht setzt, steuert die Schaltfläche nichts.

Wie du in Beispiel 4-16 sehen kannst, hat die Schaltfläche ein weiteres ARIA-Attribut: aria-controls.

Die Eigenschaft controls

Das Attributaria-controls identifiziert das Element, das die Schaltfläche steuert. Der Wert ist eine Liste mit einer oder mehreren id Referenzen. Wenn das Attribut vorhanden ist, kann ein Screenreader eine Beziehung zwischen einer Schaltfläche und einem anderen Element erkennen. JAWS zeigt diese Beziehung nicht automatisch an, aber du kannst die Tastenkombination JAWSKEY + ALT + M verwenden, um direkt zu dem kontrollierten Element zu springen.

Für Offenlegungs-Widgets wird dieses Attribut nicht gut unterstützt (JAWS ist der einzige Screenreader, der es verwendet), und es ist unklar, wie viel Bedeutung die Anbieter von Screenreadern diesem Attribut beimessen werden. Aber es schadet nicht. Für NVDA ist dies seit 2018 ein offenes Thema; eine offene Diskussion im ARIA GitHub Repository datiert auf 2019. Ob du es verwendest, bleibt dir überlassen. Bis es eine offizielle Empfehlung dafür oder dagegen gibt, verwende ich sie in den folgenden Kapiteln.

Gepresster Zustand

Das Attributaria-pressed zeigt den aktuellen "gedrückten" Zustand von Schaltflächen an.

Ein Toggle-Button ist ähnlich wie ein Kontrollkästchen, aber nicht ganz dasselbe. Abgesehen von der Gestaltung besteht der wichtigste Unterschied darin, dass ein Kontrollkästchen nur einen Zustand vermittelt (markiert/deaktiviert/gemischt), während eine Schaltfläche eine Aktion ausführt. Wenn du auf einen Toggle-Button klickst, erwartest du, dass etwas passiert. Wenn du die Schaltfläche in Beispiel 4-17 drückst, wird der Wert des Attributs aria-pressed umgeschaltet und der Status der Schaltfläche Zu Favoriten hinzufügen geändert. Client-seitige Änderungen wie diese erfordern, dass du in einer Umgebung arbeitest, die auf JavaScript angewiesen ist, weil sich der gedrückte Zustand beim Klicken ändern muss. Wenn das nicht der Fall ist und du das Steuerelement schrittweise verbessern willst, verwende stattdessen ein Kontrollkästchen. Adrian Roselli beschreibt die Unterschiede zwischen Kontrollkästchen und Umschaltknöpfen ausführlich in "Under-Engineered Toggles" und "Under-Engineered Toggles Too".

Kontrollierter Zustand

Das Attributaria-checked zeigt den aktuellen "angekreuzten" Zustand von Kontrollkästchen, Optionsfeldern und anderen Widgets an.

Du sollst aria-checked nicht für eine Schaltfläche mit der Rolle button verwenden, aber du kannst es für einen Schalter verwenden (siehe Beispiel 4-18). Ein Schalter ist eine Art von Kontrollkästchen, das Ein/Aus-Werte anstelle von angekreuzten/abgehakten/gemischten Werten darstellt. Er bietet ungefähr die gleiche Funktionalität wie ein Kontrollkästchen oder ein Umschaltknopf, aber du kannst sie für Bildschirmleser auf eine Art und Weise unterscheiden, die dem Erscheinungsbild auf dem Bildschirm entspricht. Schalter sind ein problematisches Muster in Bezug auf die Benutzerfreundlichkeit. Ich erkläre dir in Rezept 9.1, warum. Wenn du dich für die Verwendung von Schaltern entscheidest, solltest du sie gründlich mit Nutzern testen, auch mit denen, die Bildschirmleser verwenden.

haspopup Eigenschaft

Das aria-haspopup Attribut zeigt an, dass eine Schaltfläche ein anderes interaktives Pop-up-Element steuert. Die meisten Screenreader zeigen auch den Typ des Pop-up-Elements an. Das Attribut unterstützt sieben Werte: true, false, menu, dialog, grid, listbox und tree, was anzeigt, dass das referenzierte Element die jeweilige Rolle hat. true ist dasselbe wie menu.

Wenn du die Schaltfläche in Beispiel 4-19 fokussierst, wird sie je nach Screenreader-Software etwas wie "Einstellungen, Schaltfläche, Menü" (JAWS) oder "Einstellungen, Pop-up-Schaltfläche, Menü-Pop-up" (VoiceOver) anzeigen. Der Wert, den du verwendest, muss halten, was er verspricht: Wenn der Wert menu ist, sollte die Rolle des kontrollierten Elements auch menu sein und entsprechend funktionieren. JAWS sagt zum Beispiel auch entsprechende Anweisungen an, wenn ein Attribut mit einem bestimmten Wert vorhanden ist. Bei true und menu sagt es: "Drücke die Leertaste, um das Menü zu aktivieren. Navigiere dann mit den Pfeiltasten." Für Listbox, Baum und Gitter: "Zum Aktivieren drückst du die Eingabetaste."

Die Werte true und menu werden von allen Screenreadern gut unterstützt. TalkBack und Narrator unterstützen jedoch weder Grid, Dialog, Listbox noch Tree.

4.5 Deaktiviere keine Schaltflächen

Problem

Die Deaktivierung der Schaltflächen von kann den Nutzern mehr Probleme als Vorteile bringen.

Fehlendes Feedback

Wenn du auf eine deaktivierte Schaltfläche klickst, passiert nichts. Die Schaltfläche erklärt nicht, was falsch ist, oder hilft dir, das Problem zu beheben. Sie gibt keine hilfreiche Rückmeldung. Wenn der Nutzer denkt, dass seine Antworten richtig sind, kann das Fehlen von Feedback dazu führen, dass sich die Benutzeroberfläche kaputt anfühlt.

Fehlender Fokus

Deaktivierte Schaltflächen können nicht fokussiert werden, sodass Screenreader-Nutzer, die mit der Taste Tab navigieren, möglicherweise nicht wissen, dass es überhaupt eine Schaltfläche gibt. Wenn das Styling der Schaltfläche nicht offensichtlich ist, kann es Tastaturbenutzer verwirren, die versuchen, die Schaltfläche zu fokussieren.

Niedriger Kontrast

Die WCAG-Mindestkontrastregel gilt nicht für deaktivierte Steuerelemente, aber sie sind oft schwer zu lesen, besonders für Menschen mit Sehschwäche.

Täuschung

Es ist nicht immer offensichtlich, dass Schaltflächen deaktiviert sind. Manche Nutzer/innen werden versuchen, sie anzuklicken; wenn nichts passiert, können sie irritiert, verwirrt oder enttäuscht sein. Das kann daran liegen, dass das Design nicht eindeutig ist oder dass deaktivierte Schaltflächen in der Regel Call-to-Action-Wörter wie "Absenden", "Senden" oder "Bestellen" enthalten, die zum Anklicken verleiten.

Lösung

Deaktiviere die Schaltflächen nicht. Die Nutzer sollten immer die Möglichkeit haben, mit ihnen zu interagieren und Feedback zu bekommen .

Diskussion

Der Sinn der Deaktivierung von Schaltflächen ist es, vorzeitige Klicks zu vermeiden und es den Nutzern zu erschweren, beim Ausfüllen von Formularen Fehler zu machen. Entwickler nutzen diese Technik, um darauf hinzuweisen, dass etwas Wichtiges falsch ist oder fehlt und behoben werden muss, bevor der Nutzer mit dem nächsten Schritt fortfahren kann. Das klingt gut, aber ein deaktivierter Button ist nicht die beste Lösung. Es ist ein fehlerhaftes Muster. Eine Schaltfläche kann aus vielen Gründen deaktiviert werden, aber wenn man sie benutzt, muss der Nutzer herausfinden, was falsch gelaufen ist.

Anstatt Schaltflächen zu deaktivieren, gibt es mehrere Maßnahmen, die du ergreifen kannst, um Fehler im Vorfeld zu vermeiden:

  • Verwende klare Beschriftungen für deine Eingabefelder.

  • Füge Hinweise und Beschreibungen hinzu, wenn das Etikett allein nicht deutlich genug ist.

  • Teile komplexe Formulare in mehrere Schritte oder Seiten auf, um die kognitive Belastung zu verringern.

  • Aktiviere immer Schaltflächen und überprüfe Eingaben beim Absenden.

  • Gib klare Fehlermeldungen aus.

Wenn der Benutzer die Schaltfläche drückt, zeige ihm eine Liste mit Fehlern an, die auf das entsprechende Feld verweisen, oder verschiebe den Fokus auf das fehlerhafte Feld, wenn es nur eines gibt (siehe Rezept 9.4 für ).

Get Web Accessibility Cookbook now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.