Devlog #13 — Pierwszy audyt dostępności: co znaleźliśmy i naprawiliśmy

Symulacje WebGL i dostępność tradycyjnie nie łączą się dobrze. Elementy canvas są nieprzezroczyste dla czytników ekranu. Elementy sterujące są nieosiągalne z klawiatury. Współczynniki kontrastu nie spełniają WCAG AA. W końcu przeprowadziliśmy porządny audyt — oto raport o stratach i to, co z tym zrobiliśmy.

Dlaczego zrobiliśmy to teraz

Kilku nauczycieli napisało do nas z pytaniem, czy którekolwiek z symulacji można wykorzystać na lekcjach z uczniami niedowidzącymi. Szczera odpowiedź brzmiała: nie wiedzieliśmy. To było wystarczająco żenujące, by zmotywować nas do audytu. Użyliśmy Lighthouse, axe DevTools i ręcznych przejść wyłącznie klawiaturą na każdej stronie serwisu.

Podsumowanie wyników (przed)

67
Lighthouse A11y (śr.)
18
Znalezionych naruszeń axe
4
Krytyczne (WCAG A)
94
Lighthouse A11y (po)

Co znaleźliśmy

🔴Krytyczne
Pułapka klawiaturowa w canvasach symulacji
Naciśnięcie Tab wewnątrz symulacji przełączało fokus między wewnętrznymi elementami DOM biblioteki Three.js, nigdy nie wychodząc do elementów sterujących strony. Użytkownicy polegający na nawigacji klawiaturą utykali w pułapce.
Naprawa: dodano tabindex="0" do wrappera canvas oraz nasłuchiwanie klawisza Escape, które odbiera fokus canvasowi i zwraca go stronie.
🔴Krytyczne
Brak <label> na wszystkich elementach sterujących
Każdy panel sterowania symulacji miał suwaki <input type="range"> bez powiązanej etykiety — tylko wizualny tekst obok. Czytniki ekranu ogłaszały „suwak” bez żadnego kontekstu.
Naprawa: każdy suwak owinięto w <label> albo dodano atrybuty aria-label i aria-describedby tam, gdzie etykieta musiała być oddzielona.
🔴Krytyczne
Błędy kontrastu kolorów (przygaszony tekst)
Nasz token --color-muted-2 (#7a88a0) na ciemnym tle (#060d1a) dawał współczynnik kontrastu 3.4:1 — poniżej wymogu WCAG AA wynoszącego 4.5:1 dla zwykłego tekstu.
Naprawa: rozjaśniono --color-muted-2 do #8fa5c0 (4.6:1). Podobnie zaktualizowano --color-muted.
🔴Krytyczne
Brak linku „przejdź do treści”
Każda strona zmuszała użytkowników klawiatury do przechodzenia przez cały pasek nawigacji, zanim dotarli do elementów sterujących symulacją. Na stronach z 12+ pozycjami nawigacji było to nieużywalne.
Naprawa: dodano wizualnie ukryty link „Przejdź do głównej treści” jako pierwszy element otrzymujący fokus na każdej stronie — widoczny po ustawieniu fokusu.
🟡Ostrzeżenie
Canvas nie ma opisu tekstowego
Canvasy WebGL są całkowicie niewidoczne dla czytników ekranu. Użytkownik VoiceOver trafiał na symulację i nie słyszał niczego użytecznego.
Naprawa: do każdego canvasa dodano role="img" oraz aria-label ze znaczącym opisem tego, co pokazuje symulacja, a także link do wyjaśnienia tekstowego.
🟡Ostrzeżenie
Wskaźnik fokusu nadpisany przez reset CSS
Nasz globalny reset outline: none usuwał ramkę fokusu przeglądarki ze wszystkich elementów interaktywnych. Użytkownicy klawiatury nie mieli żadnej wizualnej wskazówki, gdzie znajduje się fokus.
Naprawa: usunięto globalny reset, zastępując go regułą :focus-visible z 2px bursztynowym konturem z odstępem na wszystkich elementach interaktywnych.

Najtrudniejszy problem: ruchome symulacje

Najtrudniejsze wyzwanie dostępności w symulacjach WebGL nie jest techniczne — jest koncepcyjne. Użytkownik czytnika ekranu nie może w sensowny sposób doświadczyć symulacji stada czy wahadła. Canvas to bitmapa; nie ma czego opowiadać.

Nasze podejście polegało na oddzieleniu interaktywności od doświadczenia:

To nie sprawia, że nasze symulacje są w pełni dostępne dla użytkowników z zaburzeniami wzroku — wymagałoby to zupełnie innego modelu interakcji. Ale sprawia, że otaczający kontekst i elementy sterujące są w pełni dostępne, co jest istotnym ulepszeniem.

Co jeszcze pozostaje do zrobienia