Wpadki i wypadki #23: pierwsza zasada używania ARIA

Lighthouse dodał ostatnio nową kategorię testów: dostosowanie strony do agentycznego przeglądania (ang. agentic browsing). Sprawdza ona, jak bardzo strona jest przygotowana na bycie obsługiwaną przez agenty AI. Wśród nowych testów jeden szczególnie przykuł moją uwagę: sprawdzenie poprawności drzewka dostępności.

Istnieje wiele sposobów na poprawę rzeczonego drzewka. Dowcip polega na tym, że ten najszybszy jest też często najgorszym… a przy okazji prawdopodobnie źródłem samego problemu.

Drzewko dostępności

Zacznijmy jednak od początku, czyli czym tak naprawdę jest drzewko dostępności? Otóż w momencie, gdy przeglądarka czyta kod HTML i CSS, zasadza ona tak naprawdę wręcz cały las. Z parsowania HTML-a powstaje DOM (Document Object Model) – drzewko pokazujące hierarchię i relacje między wszystkimi elementami HTML. Z parsowania CSS-a powstaje z kolei CSSOM (Cascading Style Sheets Object Model) – drzewko pokazujące relacje między stylami a elementami DOM. Z połączenia obydwóch z kolei tworzone jest drzewko renderowania – zawierające informacje o tym, co jest obecnie widoczne i w jaki sposób ma zostać wyrenderowane na ekranie. A gdzieś z boku jest sobie też drzewko dostępności. Korzysta ono z informacji z innych drzewek (głównie renderowania), żeby przekazać technologii asystującej (takiej jak czytniki ekranu), co dokładnie znajduje się na stronie.

Przykładowo weźmy przycisk:

<button>Jestem przyciskiem</button>

W drzewku dostępności będzie on przedstawiony jako element o roli button i dostępnej nazwie Jestem przyciskiem. W rezultacie czytnik ekranu dostanie informację, że gdy taki przycisk zostanie sfocusowany, należy go przeczytać jako coś typu Jestem przyciskiem, przycisk (dokładny komunikat różni się w zależności od wykorzystanego czytnika). A dzięki temu osoba używająca czytnika będzie już wiedziała, w jaki sposób takiego elementu użyć. W końcu to przycisk – standardowy element HTML, który ma ściśle określone zachowanie.

ARIA

I tutaj na scenę wkracza ARIA (Accessible Rich Internet Applications). Jest to standard opisujący różne role, stany i właściwości, które można przypisywać do poszczególnych elementów HTML, żeby prezentować je w określony sposób w drzewku dostępności. Wyobraźmy sobie hipotetyczną sytuację, w której chcemy umieścić na stronie nagłówek 10. poziomu. Nie jesteśmy w stanie zrobić tego przy pomocy HTML-a, ponieważ on udostępnia jedynie nagłówki do 6. poziomu. Tutaj na pomoc przychodzi nam ARIA, która dzięki atrybutowi [role] pozwala nadpisać rolę elementu. Dodatkowo, dzięki atrybutowi [aria-level] umożliwia także ręczne ustalenie poziomu nagłówka. Tym sposobem możemy stworzyć nagłówek 10. poziomu:

<p role="heading" aria-level="10">Jestem nagłówkiem 10. poziomu</p>

Jeśli zbadamy ten element w drzewku dostępności, zauważymy, że, faktycznie, jest reprezentowany jako nagłówek 10. poziomu.

W narzędziach developerskich Chrome'a podświetlony jest element z atrybutami [role="heading"] oraz [aria-level=10]; po prawej, w zakładce "Accessibility", jest on opisany jako nagłówek 10. poziomu.

ARIA pozwala w podobny sposób tworzyć bardziej skomplikowane konstrukcje, których nie da się stworzyć w czystym HTML-u – takie jak choćby menu rozwijane przyciskiem. Oto więc nadszedł dzień, gdy strony tworzone wyłącznie na divach mogą być w pełni dostępne…!

Pierwsza zasada używania ARIA

Zapewne nikogo nie zdziwi fakt, że to wcale nie jest takie proste. ARIA jest potężną technologią, a jak wiadomo – z wielką mocą wiąże się wielka odpowiedzialność. Stąd też powstały zasady używania ARIA. Pierwsza z nich brzmi nie mówimy o ARIA nie używaj ARIA, jeśli możesz użyć czystego HTML-a.

Wynika to z tego, że ARIA tak naprawdę jedynie zmienia opis elementu w drzewku dostępności. W żaden sposób nie wpływa na jego zachowanie. Dobrym przykładem może być tutaj obrazek. Zgodnie ze standardem HTML, jego alternatywny tekst należy dodać przy pomocy atrybutu [alt]. Taki opis trafia również do drzewka dostępności, a więc – do czytnika ekranu. ARIA pozwala go nadpisać przy pomocy m.in. atrybutu [aria-label]. Z perspektywy drzewka dostępności obydwa poniższe elementy img są takie same:

<img src="[…]" alt="Uśmiechnięty Comandeer">
<img src="[…]" aria-label="Uśmiechnięty Comandeer">
Dwa identyczne obrazki w drzewku dostępności Chrome'a; obydwa wskazują na ten sam plik graficzny i mają tekst alternatywny "Uśmiechnięty Comandeer".
Obydwa obrazki w drzewku dostępności. Pierwszy z nich wykorzystuje atrybut [alt], drugi – [aria-label]

Niemniej różnią się zachowaniem. Atrybut [alt] jest bowiem wykorzystywany przez przeglądarkę także w innych sytuacjach, np. w momencie, gdy obrazek się nie wczyta. Wówczas wyświetlana jest ikona zepsutego obrazka, a obok niej – tekst z atrybutu [alt]. W przypadku obrazka z atrybutem [aria-label] zostaje sama ikona. Innymi słowy: zastosowanie tutaj ARIA tak naprawdę obniża dostępność (osoby, którym nie wczytał się obrazek, są pozbawione dostępu do części informacji).

Dwie ikony zepsutego obrazka, jedna pod drugą; przy pierwszej znajduje się tekst "Uśmiechnięty Comandeer", przy drugiej brak jakiegokolwiek tekstu.
Szybkie porównanie obydwu sposobów dodawania tekstu alternatywnego do obrazka. Pierwszy obrazek wykorzystuje atrybut [alt], drugi – [aria-label]

Jeszcze dobitniejszym przykładem są przyciski. Żeby odtworzyć natywny element button przy pomocy ARIA, trzeba włożyć w to absurdalnie wręcz dużo pracy. O wiele łatwiej jest użyć już istniejących elementów HTML. I dokładnie o tym jest pierwsza zasada używania ARIA.

Krótki poradnik psucia (drzewka) dostępności

Pora zatem wrócić do Lighthouse’a i jego sprawdzania poprawności drzewka dostępności. Jeśli cały problem sprowadzimy faktycznie do tego, żeby drzewko było poprawne (co oznacza tak naprawdę zgodność ze standardem ARIA), to bardzo łatwo stworzyć poprawne, ale całkowicie niedostępne rozwiązania. Jeśli odpalimy Lighthouse’a na wspomnianych wyżej obrazkach, to obydwa przejdą test bez problemu. A przecież jeden z obrazków jest zdecydowanie mniej dostępny od drugiego!

Wyniki testów Lighthouse'a z kategorii "Agentic Browsing"; sprawdzanie poprawności drzewka dostępności zakończyło się sukcesem.
Lighthouse odpalony na stronie z naszymi obrazkami

Używanie HTML-a zamiast ARIA w większości sytuacji będzie prowadzić do tworzenia dostępniejszych rozwiązań. I, paradoksalnie, będzie też nas chronić przed tworzeniem niepoprawnego drzewka dostępności. Jeśli używa się elementów HTML zgodnie z ich przeznaczeniem, niemal niemożliwym jest wyprodukować przy tym niepoprawne drzewko dostępności. Natomiast używając ARIA jest o to zadziwiająco łatwo. Im bardziej skomplikowany komponent chcemy opisać przy pomocy tego standardu, tym większa szansa, że coś pomylimy. Wynika to z samej złożoności ARIA. Niektóre role można zagnieżdżać tylko wewnątrz innych, konkretnych ról (np. opcje menu muszą znaleźć się w elemencie z rolą menu). Inne z kolei wymagają dodania odpowiednich atrybutów (np. wspomniane już opcje menu wymagają atrybutu [aria-checked]). Nawet wspominany już wcześniej przycisk rozwijający menu to zbiór kilku różnych ról i atrybutów ARIA – a przecież to jeden z prostszych elementów interfejsu!

Innymi słowy: ARIA jest najczęściej rozwiązaniem problemu, który został spowodowany przez ARIA. I często najlepszym rozwiązaniem jest usunięcie części ARIA, zamiast dokładania kolejnej warstwy ARIA. I zanim padniemy ofiarą satiacji semantycznej, warto raz jeszcze powtórzyć pierwszą zasadę używania ARIA: nie używaj ARIA, jeśli możesz użyć czystego HTML-a.

PS wesołego świętowania Światowego Dnia Świadomości Dostępności!

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Wymagane pola są oznaczone *

Ta strona używa Akismet do redukcji spamu. Dowiedz się, w jaki sposób przetwarzane są dane Twoich komentarzy.