Wie wir Yandex Cloud mit dem Gravity UI Design System zugänglicher gemacht haben

Hallo, ich heiße Wowa Timofejew und bin Manager für technische Projekte bei Yandex Cloud. In diesem Artikel teile ich, wie wir die Website der Cloud-Plattform barrierefreier gemacht haben, wie viele Iterationen wir durchlaufen sind und welche Rolle Gravity UI dabei gespielt hat.

Die Grundlage der Barrierefreiheit aller Services ist, wie gut sie die Arbeit mit Screenreadern (Programmen für Bildschirmzugriff) unterstützen. Über diese Programme nehmen Nutzer:innen mit Einschränkungen die Oberfläche wahr und interagieren damit.

Websites sind da keine Ausnahme. Und wir mussten herausfinden, wie barrierefrei Yandex Cloud für alle Nutzer:innen ist.

Bei Yandex verstehen wir unter Barrierefreiheit, dass unsere Services von allen komfortabel genutzt werden können — unabhängig von vorübergehenden oder dauerhaften körperlichen Einschränkungen. Zum Beispiel sind aktuell 16 Yandex-Services für blinde Nutzer:innen angepasst: Lavka, Go, Suche, Browser, Mail und andere. Bei der Arbeit an der Barrierefreiheit jedes Services hilft das Team für nichtvisuelles Testen — und auch in dem Fall, von dem ich in diesem Artikel erzähle, ging es nicht ohne deren Unterstützung.

Spoiler: Als Ergebnis des Testens wurden mehrere strittige Punkte bei der Arbeit mit Screenreadern gefunden, die sich in konkrete Aufgaben verwandelt haben.

Aber alles der Reihe nach.

Alles begann mit Gravity UI

Gravity UI ist ein Designsystem und eine Komponentenbibliothek, auf der die Website von Yandex Cloud und Dutzende anderer Cloud-Produkte basieren. Sie ist als Open Source veröffentlicht und für alle verfügbar (es freut uns, dass die Aktivität im Community-Chat in den letzten sechs Monaten spürbar gestiegen ist).

Was wir haben:

  • набор базовых React‑компонентов;
  • eine Builder-Bibliothek für Landingpages;
  • ausführliche Guides von Designer:innen zur Nutzung der Komponenten;
  • eine Bibliothek in Figma;
  • ein Set aus fast 600 fertigen Icons;
  • ChartKit — ein Paket zur Datenvisualisierung;
  • Yagr — performantes Chart-Rendering auf Basis von uPlot;
  • i18n — ein Paket zur Lokalisierung der UI;
  • andere nützliche Bibliotheken.

Im März 2024 erschien ein Update der Kernbibliothek — UIKit Version 6. Darin wurde die Komponente List aktualisiert, Unterstützung für den RTL-Parameter in allen Komponenten hinzugefügt sowie ein Paket an a11y-Verbesserungen zur besseren Barrierefreiheit umgesetzt.

Was ist neu in UIKit Version 6
  1. Komponente List 2.0. In UIKit gab es von Anfang an List, aber wir wollten einige Dinge daran verbessern. Beim Sammeln der Anforderungen entstand folgende Liste:

    • Unterstützung verschiedener Größen und Breiten;
    • Icon am Listenelement, unterschiedliche Anzahl und Position von Icons;
    • Unterstützung von States;
    • unterschiedlicher Content in Listenelementen (einzeilig, mehrzeilig oder eine Nutzerliste);
    • Unterstützung verschiedener Separator- und Gruppierungsarten.

    Das sind wesentliche Änderungen, deshalb haben wir List 2.0 erstellt. Aktuell erscheint sie in der prestable-Version, aber wir empfehlen Nutzer:innen, darauf umzusteigen und Feedback zu geben.

  2. RTL. Wenn eure Apps oder Websites auf Hebräisch, Arabisch und anderen Sprachen mit Schreibrichtung von rechts nach links angezeigt werden sollen, braucht ihr Unterstützung für RTL-Standards. Dabei gilt in RTL:

    • ein eingefügtes Wort in lateinischer Schrift wird von links nach rechts geschrieben;
    • Zahlen werden von links nach rechts geschrieben;
    • Satzzeichen im Arabischen werden ebenfalls von links nach rechts geschrieben usw.

    In allen Komponenten haben wir den RTL-Parameter unterstützt. Damit ein vollständiges Beispiel zur Hand ist, haben wir eine Promo-Seite auf Arabisch erstellt. Wie das umgesetzt ist, kann man im Quellcode von landing sehen. Außerdem gibt es Beispiele im storybook.

  3. Barrierefreiheit (a11y):

    • wir haben dem Projekt das eslint-Plugin hinzugefügt;
    • Tastaturunterstützung für den clickable- und closable-State der Persona-Komponente;
    • onClick bei 15 nicht-interaktiven Komponenten deaktiviert;
    • Tastaturunterstützung in der Komponente SelectionTable.

Wie wir zu den a11y-Verbesserungen gekommen sind

Dabei half uns das Team für nichtvisuelles Testen und sein Leiter Anatolij Popko. In einem Meeting testete Anatolij Schritt für Schritt die Sandbox und die Website von Gravity UI, um zu verstehen, welche Barrierefreiheitsprobleme es aktuell gibt.

Wir prüften die Barrierefreiheit der Komponenten, indem wir uns mit der Tastatur und speziellen Screenreader-Kommandos über die Website bewegten.

Visuell sah das so aus:

Full screen image

Nach dem Meeting hatte das Team konkrete Aufgaben, und auf GitHub sind drei neue Issues zu den Basiskomponenten erschienen.

Mehr dazu:

  • In der Dropdown-Liste lässt sich die zweite Ebene der Elemente
    nicht öffnen
    per Tastatur, nur per Mausklick.
Full screen image
  • Es ist unklar, welches Element in der Markdown-Aufzählung in der Select-Komponente ausgewählt ist.

  • Buttons ohne Textlabels, die nur grafisch gekennzeichnet sind, werden als einfach nur “Button” oder “Radio-Button” vorgelesen. Dieser Bug tritt nur auf der Landingpage auf; die Komponente selbst unterstützt aria-label, aber wir haben es nicht genutzt.

Full screen image

Als Ergebnis verstanden wir: Wenn wir nicht Dutzende Anmerkungen gefunden haben, ist die Barrierefreiheit der Bibliothek bereits auf einem guten Niveau. Komponenten außerhalb eines realen Kontexts zu testen, ist sehr schwer — deshalb beschlossen wir, die Barrierefreiheit eines fertigen Produkts zu prüfen. So konnten wir zusätzliche a11y-Verbesserungen finden.

Barrierefreiheit bei Yandex Cloud

Inspiriert vom Update von Gravity UI beschlossen wir, unsere Services auf Barrierefreiheit zu testen: Wir starteten mit der Website von Yandex Cloud und wollten diese Erfahrung später auch auf andere Interfaces übertragen.

Es gibt eine Reihe von Standards, deren Einhaltung Barrierefreiheit ermöglicht. Um die Interfaces von Yandex Cloud zuverlässig zu testen und besser zu verstehen, wie bequem unsere Website für alle ist, haben wir ein Audit durchgeführt.

Audit zur Barrierefreiheit

Wir wandten uns erneut an Kolleg:innen aus dem Team für nichtvisuelles Testen und an Anatolij, um die Website gemeinsam zu testen, Probleme zu dokumentieren und zur Überarbeitung mitzunehmen. Insgesamt gab es zwei Iterationen mit fast einem Monat Abstand — Test und Retest.

Während des Testens haben wir einen ganzen Pool an Änderungen festgehalten, die umgesetzt werden mussten.

Auf der Startseite

  • Das Such-Control musste überarbeitet werden. In unserer UI ist die Suche als Suchbereich mit einer Lupen-Icon umgesetzt. Beim Klick darauf öffnet sich ein Eingabefeld für die Anfrage. In der vorherigen Umsetzung waren das für den Screenreader unabhängige Elemente, was blinde Nutzer:innen verwirrte.

    image

  • Bei der Sprachauswahl verwendeten wir das Zustandsattribut “eingeklappt”, obwohl es eigentlich ein Auswahl-Button und keine Dropdown-Liste war. Es gab keine Beschriftung “Sprache”, außerdem fehlte ein Leerzeichen im Übergang “Sprache — Region”.

  • Im Account-Menü wurde der Fokus nicht “eingesperrt”: Bei Aktivierung konnte der/die Nutzer:in den Menüeinträgen entkommen.

  • Das main-Tag war auf der Startseite doppelt vorhanden, daher musste eines entfernt werden.

  • Abschnitt mit Beispielen: Es sollte ein Tab statt eines Buttons verwendet werden.

Full screen image
  • In der Beispiel-Card war der Text in aria-describedby versteckt, wodurch der Screenreader den Text nur einmal vorlas — das ist beim Studieren wichtiger Informationen unpraktisch. Als wir den Bug untersuchten, verstanden wir, dass es sich lohnt, ein umfassendes Refactoring der Card-Komponente zu machen, und haben ein Issue erstellt, in dem man Details zu den Änderungen erfahren und an der Diskussion teilnehmen kann.
  • Fokusproblem: Beim Aufklappen der obersten Menüebene muss der Fokus in das Untermenü verschoben werden.
  • TabIndex musste bei der obersten Menüebene entfernt werden. Die aktuelle Umsetzung führte zu einer doppelten Aufzählung aller Menüpunkte.
  • Der Tastaturfokus musste in der Navigation “eingesperrt” werden, wenn sie aufgeklappt ist. Andernfalls kann man aus dem Menü auf die Seite “hinausfallen” und danach nicht mehr zurückkehren.
  • Yandex Cloud war von einer Liste umschlossen. Die Überschriften der Linklisten im Footer waren in ein Listenelement eingebettet, daher erkannte NVDA sie als Bestandteil und las dieselbe Liste dem/der Nutzer:in zweimal vor.
  • Es fehlten Beschriftungen für die Links zu AppStore und Google Play. Zum Testzeitpunkt wurden URL-Fragmente vorgelesen, wodurch für den/die Nutzer:in nichts verständlich war.

Bereich “Blog”

  • Die Buttons “Alle Themen” und “Alle Services” waren nicht korrekt als Buttons zugeordnet. Die Select-Buttons haben ihren Inhalt nicht angesagt.
  • Es wurde Barrierefreiheitsunterstützung in Listen benötigt: Beim Öffnen einer Dropdown-Liste muss der Fokus der Screenreader-Programme auf die Elemente dieser Liste wechseln. Zusätzlich sollte eine vereinfachte Navigation zwischen ihnen mit den normalen Pfeiltasten unterstützt werden — ohne irgendwelche Tastenkombinationen.

Blogartikel

  • In den Breadcrumbs fehlte das Element “Sie sind hier”.
  • Der Fokus musste im Dialog “eingesperrt” werden.
  • Der Favoritenzähler hatte keinen Namen. Der Zähler war ein Button mit Icon und Zahl. Screenreader lasen die Zahl vor — ohne Icon war nicht klar, was der Button macht.

Alle Aufgaben haben wir in einem Epic gesammelt und mit der Umsetzung begonnen. Für einen Teil der Aufgaben wurden Issues auf GitHub erstellt.

Die interessantesten Cases beschreibe ich genauer.

Komponente Select

Full screen image

Beim Testen stellten wir fest, dass bei der Tastaturnavigation die Namen der Listenelemente nicht vom Screenreader angesagt werden. Teilweise konnten wir das Problem mithilfe des Attributs aria-activedescendant beheben, aber nicht vollständig.

Welche Probleme geblieben sind

  • In Safari funktioniert dieser Ansatz nicht, und aktuell ist unklar, wie wir das lösen.

  • Der Suchfilter wird nicht immer unterstützt (eigentlich nie — die Unterstützung ist schlicht nicht implementiert). Üblicherweise wird aria-activedescendant am Hauptelement der Dropdown-Liste gesetzt und verweist auf das ausgewählte Element in der Liste. Derzeit wird es am Button gesetzt, der die Dropdown-Liste öffnet. Wenn man Pfeil nach oben oder unten drückt, ändern wir am Button den Wert von aria-activedescendant auf das vorherige oder nächste Listenelement. So kann das Screenreader-Programm vom ausgewählten Button ablesen, welches Element gerade ausgewählt ist.

    Das Problem beim Suchfilter ist, dass dessen Eingabefeld kein aria-activedescendant-Attribut hat. Wenn jemand den Fokus auf das Eingabefeld des Filters setzt und dort etwas eingeben möchte, kann das Screenreader-Programm daraus nicht lesen, welches Listenelement aktiv ist — und die Navigation durch die Liste mit den Pfeiltasten funktioniert nicht.

  • Ausgewählte Optionen sind nicht markiert; wir müssen ein Attribut hinzufügen, z. B. aria-selected.

Das Issue mit den aktuellen Problemen kann man sich hier ansehen.

Full screen image

Breadcrumbs sind ein Navigationselement, das den Pfad des/der Nutzer:in auf der Website zeigt. In unserem Fall las der Screenreader den gesamten Pfad vor, und es war unmöglich zu verstehen, in welchem Teil der Website sich die Person befindet. Außerdem wurde die gesamte Komponente einfach als Linkliste dargestellt.

Wir entschieden uns, von Standards abzuweichen und die Aufgabe auf einfache und optimale Weise zu lösen — indem wir für den Screenreader das Label “Sie sind hier” hinzugefügt haben. Am Ende kombinierten wir den Standardansatz und das Label.

Während der Umsetzung stellte sich heraus: Damit dieses Label vorgelesen wird, muss es an ein Element gehängt werden, das von Screenreadern nicht ignoriert wird. Es war einfacher, das Label an die konventionelle Struktur zu hängen, als einen Weg zu erfinden, sie zu umgehen. Trotzdem ist das Label weiterhin nützlich: Es hilft dem/der Nutzer:in schneller zu verstehen, dass er/sie gerade Breadcrumbs hört.

Bilder ohne Beschriftung

Einige Bilder auf der Website waren ohne Beschriftung platziert, und der Screenreader las sie als “Bild” vor. Diese Information bringt dem/ der Nutzer:in keinen Nutzen und vermittelt keine Vorstellung vom Interface, daher beschlossen wir, Bilder ohne Beschriftung vor dem Screenreader zu verstecken.

Reihenfolge des Textes in Blöcken

Full screen image

An mehreren Stellen auf unserer Website werden Informationen als einheitlicher Block dargestellt, z. B. eine Event-Card oder eine Artikel-Card im Blog.

Wir bemerkten, dass Screenreader Informationen in einer Reihenfolge vorlesen, der sehende Nutzer:innen nicht folgen. Bei der Event-Card las der Screenreader die Daten so vor: Registrierungsstatus, Zeit, Ort und erst danach Titel und Beschreibung des Events.

Normalerweise folgt man nicht einem linearen Pfad: Man schaut zuerst auf die Überschrift, dann auf den Untertitel und das Bild. Das Problem ist, dass Screenreader Elemente in der Reihenfolge lesen, in der sie im DOM-Baum der Seite angeordnet sind. Um die Reihenfolge zu korrigieren, mussten wir sie neu zusammensetzen.

Full screen image

Wir waren überrascht, aber in einigen Kombinationen aus “Betriebssystem — Browser” hat das nicht funktioniert. Zum Beispiel blieb das Problem in Mozilla Firefox unter macOS bestehen — trotz der Änderung der Reihenfolge im DOM-Baum. Hoffen wir, dass die Firefox- Entwickler dieses Verhalten in neuen Browser-Versionen beheben.

Modale Fenster

Full screen image

Wenn ein:e sehende:r Nutzer:in ein Pop-up im Interface öffnet, fällt der Blick auf den Inhalt dieses Fensters. Gleichzeitig bleibt der gesamte Seiteninhalt weiterhin zugänglich, und bei Bedarf kann man die Aufmerksamkeit wieder darauf richten.

Wenn die Arbeit mit der Website über einen Screenreader erfolgt, ändert sich die Situation. Wenn das Pop-up nicht modal gemacht wird, hat es keine Grenzen. Infolgedessen wird die Navigation auf der Seite schwieriger: Man kann versehentlich aus dem Pop-up herausnavigieren, indem man die Navigation über Elemente verwendet.

Für modale Fenster gibt es einen Standard, und wenn man ihm folgt, ist es nicht zwingend notwendig, alle Pop-ups im Interface einzusperren.

Im Testprozess kamen wir jedoch zu dem Schluss, dass es eine gute Praxis ist, Pop-ups modal zu machen — das vereinfacht die Nutzung der Website mit Screenreadern.

Wir beschlossen, alle Pop-ups modal zu machen. Dabei ließen wir den Nutzer:innen die Möglichkeit, ein alternatives Nutzungsszenario für solche Fenster einzustellen.

Ihr könnt ein solches Szenario konfigurieren, indem ihr role="dialog", aria-modal="true" setzt. In der Kombination VoiceOver + Firefox wird diese Lösung nicht unterstützt: Details stehen im geschlossenen Issue.

Diplodoc

Angesteckt von unserer Aktivität haben die Entwickler der Plattform zur Erstellung technischer Dokumentation Diplodoc eine Reihe von a11y-Verbesserungen in ihrem Produkt umgesetzt:

  • Sie haben alle zusätzlichen Syntax-Elemente von YFM (Yandex Flavored Markdown) geprüft und so umgeschrieben, dass sie für Screenreader sichtbar sind.
  • Sie haben den Workflow bei der Nutzung der Dokumentation per Tastatur verbessert: die Reihenfolge der Elementauswahl korrigiert und die Möglichkeit der Auswahl für alle interaktiven Elemente hinzugefügt.
  • Sie haben korrekte Beschriftungen und Kennzeichnungen für UI-Elemente ergänzt, was die Nutzung des Services für Nutzer:innen mit Screenreadern deutlich vereinfacht.

Da wir Diplodoc zur Anzeige unserer Dokumentation verwenden, haben diese Verbesserungen auch die Barrierefreiheit der Dokumentation auf der Website von Yandex Cloud erhöht.

Ergebnisse und Pläne

Wir haben die ersten Schritte unternommen, um die Interfaces von Yandex Cloud für alle Nutzer:innen barrierefreier zu machen. Als Nächstes müssen wir die Erfahrung auf andere Interfaces des Services übertragen und die Probleme beheben, die wir aktuell kennen.

Gravity UI hat unsere Arbeit an der Barrierefreiheit erleichtert, und wir arbeiten weiter an offenen Issues mit dem Label a11y. Zum Zeitpunkt des Schreibens des Artikels haben wir 14 offene und 24 geschlossene Issues — ihr könnt sie euch hier ansehen.

Full screen image

Wir freuen uns auf eure PRs und Kommentare zur Barrierefreiheit und zur Nutzung der Services — sowie auf Beispiele, wie ihr Gravity UI auf euren Websites einsetzt.

image

Wladimir Timofejew
Manager für technische Projekte bei Yandex Cloud

Wie wir Yandex Cloud mit dem Gravity UI Design System zugänglicher gemacht haben

Sign in to save this post