Next Level Accessibility: 5 Ways I Made the freeCodeCamp Guide More Usable for People with Disabilities

Barrierefreiheit der nächsten Stufe: 5 Möglichkeiten, wie ich den freeCodeCamp-Leitfaden für Menschen mit Behinderungen benutzerfreundlicher gemacht habe

Ich habe den größten Teil des Hacktoberfests 2017 damit verbracht, mit einigen großartigen Leuten drüben beim freeCodeCamp zu arbeiten. Mein Fokus lag speziell darauf, dabei zu helfen, die Zugänglichkeit ihrer Guide -Site auf die nächste Stufe zu heben.

Als ich die Seite zum ersten Mal sah, wusste ich, dass sie eine fantastische Ressource für viele Leute da draußen sein würde, also nahm ich die Herausforderung an, um sicherzustellen, dass ihre Benutzerfreundlichkeit für alle erstklassig ist!

Die Arbeit an der Seite hat auch viel Spaß gemacht, da sie mit React erstellt wurde, was einige zusätzliche Codierungsherausforderungen mit sich brachte.

Sehen wir uns gemeinsam die 5 Probleme an, die ich gefunden habe, und wie ich sie angegangen bin!

Eines der ersten Dinge, nach denen ich auf einer Website überprüfe, ist, ob ein Link zum Überspringen der Navigation verfügbar ist. Navigationslinks überspringen sind ein kleines, aber praktisches Feature für jede Website, das nur für Tastatur- oder Screenreader-Benutzer verfügbar ist. Wieso den?

Das Problem

Ohne einen Link zum Überspringen der Navigation müssten Benutzer, die nur die Tastatur zum Tab verwenden, jedes Mal, wenn die Seite neu geladen wird, durch jeden Link in der Seitenleiste navigieren. Da viele Links verfügbar sind, wäre das Navigieren durch diesen Abschnitt umständlich.

Die Lösung

Das Implementieren eines Navigationslinks zum Überspringen ist ganz einfach. Es ist normalerweise das erste Element im DOM (Document Object Model) und beim Klicken wird der Tastaturfokus an das Seitenelement gesendet, das den Hauptinhalt der Seite enthält.

Der von mir hinzugefügte Link war codiert als:

 <a className="skip-link sr-only sr-only-focusable" href="#main"> Skip to main content </a>

Der #main Wert im href -Attribut sendet den Tastaturfokus an das Seitenelement, das das id="main" -Attribut enthält.

Damit dieses Seitenelement den Tastaturfokus erhält, musste ich dem Container ein tabindex Attribut hinzufügen:

 <main className="main" id="main" tabIndex="-1"> { props.children() } </main>

Das Hinzufügen des tabindex -Werts von -1 ermöglicht es einem nicht fokussierbaren Element, den Fokus programmatisch zu erhalten, wird aber aus der natürlichen Tab-Reihenfolge ausgelassen.

Das Ergebnis

Wenn die Skip-Navigation vorhanden ist, können Personen, die eine Tastatur verwenden, wiederholte Bereiche wie den seitlichen Navigationsbereich überspringen, um den Hauptinhaltsbereich einfach zu erreichen.

Animiertes GIF, das den Link „Zum Inhalt springen“ zeigt, der nur bei Fokus sichtbar ist.

Sehen Sie sich die vollständige Codeänderung in der PR (Pull Request) an: Skip-Link #4175 hinzugefügt .

Verbesserung der Barrierefreiheit Nr. 2: Fehlende Beschriftung im Suchfeld

Mir ist aufgefallen, dass dem input ein label fehlte. Eine zugeordnete label für jede Formulareingabe ist der Schlüssel zu einer erfolgreichen input . Wieso den?

Das Problem

Wenn input eine label fehlt , können Bildschirmlesegeräte den beabsichtigten Zweck des Felds nicht genau beschreiben. Stellen Sie sich für einen Moment einen Link ohne Text vor; was macht dieser link

Die Lösung

Dieser war ziemlich geradlinig. Das Hinzufügen eines label zu einer input besteht darin, das label -Element mit einem for -Attribut zu erstellen und es dann mit einer input mit einer id zu verknüpfen.

Um das aktuelle Design der Website nicht zu stören, habe ich auch die srOnly Prop hinzugefügt, damit das label visuell ausgeblendet wird.

Das label wurde wie folgt codiert:

 <ControlLabel htmlFor="searchInput" srOnly={ true }> Search </ControlLabel>

Dann habe ich für das vorhandene input einfach die id='searchInput' hinzugefügt.

Das Ergebnis

Wenn Benutzer von Screenreadern jetzt zum Suchfeld navigieren, hören sie den label „Suche“ und haben mehr Kontext zu dem, was erwartet wird.

Screenshot der Suchsteuerung, nachdem das Label hinzugefügt wurde; keine optischen Veränderungen!

Sehen Sie sich die vollständige Codeänderung in der PR an: Search input a11y updates #4123 .

Verbesserung der Barrierefreiheit Nr. 3: Rollenanpassungen in der Seitenleiste

Bei der Untersuchung des HTML-Quellcodes ist mir aufgefallen, dass einige der Seitenleistenelemente fälschlicherweise role="presentation" -Attribute enthielten. Mir ist auch aufgefallen, dass einige Elemente als div s anstelle eines angemessenen, semantischen Markups gekennzeichnet waren. Dies erforderte eine gewisse Anpassung. Wieso den?

Das Problem

Bei diesem Abschnitt der Website gab es zwei Probleme:

  1. Wenn Sie role="presentation" auf ein Element anwenden, entfernt dies alle semantische Bedeutung. Mit anderen Worten, wenn ein Screenreader auf das Element trifft, gibt es keine sinnvolle Ankündigung, um den Benutzer darüber zu informieren, wofür das Element ist. Stellen Sie sich einen Link auf einer Seite vor, aber sein Text hat die gleiche Farbe wie der Inhaltstext und ist nicht unterstrichen. Woher wissen Sie, dass es sich um einen Link handelt?
  2. Das andere Problem hier ist, wenn div Elemente verwendet werden, um eine sinnvolle Struktur zu markieren. Wie Sie vielleicht wissen, haben div -Elemente keine semantische Bedeutung und sind normalerweise reserviert, um eine Struktur auf einer Seite zu erstellen. In Fällen, in denen sie anstelle von nativ semantischen Elementen verwendet werden, müssen Sie das entsprechende role anwenden, um diese Bedeutung zu vermitteln.

Die Lösung

  1. Für jedes Navigationslistenelement und jeden Link habe ich einfach die role entfernt, damit die semantische Bedeutung für Screenreader-Benutzer durchscheinen kann.
  2. Für dynamische Komponenten, die div -Elemente generierten, habe ich entsprechende role angewendet, einschließlich role="list" für die PanelGroup Komponente und role="listitem" für alle Instanzen der Panel -Komponente.

Das Ergebnis

Wenn die role -Requisiten angepasst sind, hören Screenreader-Benutzer klare und präzise Ansagen, wenn sie auf diese Elemente stoßen, einschließlich:

  • Instanzen der Link Komponente werden als „Link“ -Element angekündigt – sehr wichtig, und;
  • Die PanelGroup und Panel -Komponentenelemente werden als "Listen" -Element angekündigt. Infolgedessen wird auch die Gesamtzahl der Artikel bekannt gegeben, die einen Kontext dafür geben, wie viele Artikel auf der bevorstehenden Reise verfügbar sind.

Screenshot der Seitenleiste nach Anpassungen der Rollenattribute; keine optischen Veränderungen!

Sehen Sie sich die vollständige Codeänderung in PR: Side nav a11y updates #4093 an .

Zugänglichkeitsverbesserung Nr. 4: Die Verfügbarkeit von Suchergebnissen wurde nicht angekündigt

Als sehender Benutzer war mir bewusst, dass eine Suche erfolgreich war, da der Hauptinhaltsbereich seinen Inhalt änderte, um eine Auflistung von Artikeln anzuzeigen. Aber was ist mit einem blinden Screenreader-Benutzer?

Das Problem

Wenn ein Screenreader-Benutzer den Suchtext eingegeben und die Enter gedrückt hat, wird nichts angesagt, was auf eine erfolgreiche Suche oder Ergebnisse hinweist. Wie kann jemand wissen, wann Artikel verfügbar sind, um voranzukommen und diese neuen Inhalte zu entdecken?

Die Lösung

Damit die aktuelle Ergebniszahl bekannt gegeben werden kann, habe ich eine neue, visuell versteckte aria-live Region erstellt. Diese Region wird mit neuen Inhalten gefüllt, wenn neue Suchergebnisse vorhanden sind.

Die Region wird mit einem div mit einigen zusätzlichen Attributen ausgezeichnet:

  • aria-live="polite" erstellt die "Live"-Region und weist Screenreader an, zu warten, bis andere Prozesse abgeschlossen sind, bevor sie ihren Inhalt ankündigen.
  • aria-atomic="true" weist Screenreader an, den gesamten Text innerhalb der Region anzukündigen, nicht nur den geänderten Text.
  • role="status" legt die Erwartung fest, dass Screenreader den Live-Inhalt als "beratende" Informationen interpretieren. Mit anderen Worten, es ist ziemlich wichtig, aber nicht kritisch (da die Leute vorwärts navigieren und Inhalte selbst entdecken könnten).

So sieht das endgültige Code-Snippet aus:

 <div aria-atomic="true" aria-live="polite" className="sr-only" role="status"> {`${results.length} result${results.length === 1 ? '' : 's'} found`} </div>

Beachten Sie die Verwendung des ES6-Vorlagenliterals zum Interpolieren des Inhalts sowie zum Ausführen einer ternären Bedingungsanweisung zum Anpassen an einen Plural- oder Singularzustand.

Das Ergebnis

Jetzt wird bei aktivem Screenreader nach Eingabe eines Suchbegriffs die Anzahl der Ergebnisse per Hilfstechnologie angesagt: „20 Ergebnisse gefunden!“

Screenshot der Suchergebnisse nach dem Hinzufügen der Live-Region; keine optischen Veränderungen!

Sehen Sie sich die vollständige Code-Änderung in der PR an: Search Results Announcements #5137 .

Beim Navigieren mit einer Tastatur ist mir aufgefallen, dass nach dem Klicken auf einen Link zum Laden des Seiteninhalts die Fokusanzeige auf dem aktuellen Element blieb. Dies war ein Problem. Wieso den?

Das Problem

Ohne eine ordnungsgemäße Fokusverwaltung müssten Nur-Tastatur- oder Screenreader-Benutzer durch die gesamte Sidebar-Navigation navigieren, um zum Seiteninhalt zu gelangen. Nicht nur das, es gibt auch keine hörbare Ankündigung, die den Benutzer darauf hinweist, dass etwas beim click() Ereignis stattgefunden hat.

Die Lösung

Die Lösung, mit der ich am Ende ging, war ein bisschen wie ein Hack. Normalerweise würden Sie ein ref -Prop für den Inhaltscontainer erstellen, dann das ref Objekt nach oben und an die Komponente übergeben, die die Seitenleisten-Link-Elemente generiert, und dann focus() auf den Container auf click() setzen. Dies war keine mögliche Lösung, da die Site etwas namens Gatsby verwendet und es ein Problem mit der Übergabe von Objekten an Link - Komponenten gibt. Ich bin mir des Problems nicht wirklich sicher, aber es hat einfach nicht zusammengearbeitet.

Um diese Einschränkung zu umgehen, ging meine Lösung so:

  1. Ich habe jeder der entsprechenden Seitenleisten- Link -Komponenten ein data-navitem="true" -Attribut hinzugefügt.
  2. Beim click() -Ereignis lädt die Article -Komponente mit dem angeforderten Inhalt und setzt document.activeElement auf das angeklickte Link-Element.
  3. Innerhalb der Methode componentWillMount() der Article -Komponente überprüfe ich, ob das aktuell fokussierte Element (der Seitenleisten-Link über document.activeElement) das data-navitem Attribut hat.
  4. Wenn diese Bedingung true ist, verschieben Sie den Tastaturfokus auf das article .

Das Ergebnis

Wenn nun jemand, der die Tastatur verwendet, einen der Unternavigationslinks in der Seitenleiste aktiviert, verschiebt sich der Tastaturfokus auf den Inhaltscontainer des article . Und dies bietet auch Kontext für Screenreader-Benutzer und vermittelt, dass bei click() etwas passiert ist.

Animiertes GIF, das die Fokusverwaltung für den Artikel beim Klicken auf den Link in der Seitenleiste zeigt.

Sehen Sie sich die vollständige Codeänderung in PR: NavItem focus #7818 an .


Und da haben wir es! Mit diesen wenigen Anpassungen hat sich die Zugänglichkeit und Benutzerfreundlichkeit der freeCodeCamp Guide- Site erheblich verbessert! Die Benutzer können die Website bequemer und erfolgreicher nutzen.

Dies ist nur ein grober Überblick über einige Probleme, die ich angegangen bin, aber ich weiß, dass es noch mehr zu tun gibt. Jeder im freeCodeCamp Guide Repo war sehr freundlich und bemüht, mir bei der Beantwortung meiner anfängerhaften React-Fragen zu helfen, also zögern Sie nicht, wenn Sie helfen möchten!

Fröhliches Hacken! 💻😄💖

Zurück zum Blog