Nieśmiało wracam na bloga po 3 miesiącach przerwy. Imprezuję całe noce (przy akompaniamencie kołysanek wszelakich), z kolei za dnia podróżuję (z wózkiem po osiedlu). Jednak wpadłam tutaj na chwilę porozmawiać o dostępności w naszym internecie. O praktykach prostych, aczkolwiek zbawiennych dla wielu, drogich użytkowników naszych aplikacji.
Na samym początku zapraszam Ciebie do przeczytania części 1 oraz części 2 tego cyklu artykułów. A teraz, bez zbędnych ceregieli, przejdźmy do konkretów.
1. Linki poprawniej.
Zacznijmy delikatnie, od niewinnych linków. Wiemy już, jak powinien wyglądać prawilny, dostępny odnośnik. Teraz zastanówmy się nad pytaniem: jak on powinien działać?
Na samym początku musimy zgodzić się, że powszechnie znany link <a href="/wyniki">Czytaj więcej</a>
nie wystarczy. Otóż większość czytników pozwala użytkownikowi przeglądać wszystkie dostępne odnośniki na całej stronie. Tekst „Czytaj więcej” jest dla użytkownika bezużyteczny. Jeśli strona, nie daj Boże, posiada kilka takich przycisków „Czytaj więcej” – korzystanie z niej na czytniku jest po prostu męczące.
title
A więc ustaliliśmy sobie, że link powinien mieć czytelny opis. Ze względu na user-friendly UX często nie jesteśmy w stanie upchnąć czytelnej nazwy na front, wobec tego schowajmy ją do jakiegoś atrybutu. Którego? Odpowiedź wydaje się oczywista – standardowy odnośnik w internetach posiada opis w atrybucie title
. Dla przykładu:
<a href="/wyniki" title="Poznaj wyniki konkursu na najlepszą rodzinną grę planszową.">Czytaj więcej</a>
Powiedz mi teraz: czy to wystarczy? Daj sobie minutę na zastanowienie.
Otóż atrybut title
może być istotny w kontekście SEO, jednak nie jest on widoczny dla większości czytników ekranu! Wydawcy zablokowali możliwość odczytywania jego wartości ze względu na nadgorliwych programistów, którzy lubili upychać do niego cały wór klikających się słów kluczowych. Piszę w czasie przeszłym, ponieważ obecnie takie zachowanie jest powszechnie uznawane za złą praktykę.
Poza tym atrybut title
w przeglądarkach jest dostępny tylko dla użytkowników myszek w postaci tooltipa (użytkownicy korzystający z klawiatury oraz urządzeń mobilnych są w tym przypadku wykluczeni).
aria-label
Skończmy już ten przydługi wstęp. Z punktu widzenia a11y – prawidłowy link powinien korzystać z atrybutu aria-label
, który w sposób unikalny opisywałby jego przeznaczenie. Dla przykładu:
<a href="/wyniki" aria-label="Czytaj więcej: Poznaj wyniki konkursu na najlepszą rodzinną grę planszową.
">Czytaj więcej</a>
Warto tu wspomnieć, że W3C rekomenduje rozpoczynanie opisu w atrybucie aria-label
od tekstu, który jest widoczny w opisie linku na UI (źródło). Ma to zapewnić „spójną komunikację”.
Kolejna ważna uwaga: daj znać użytkownikowi, jeśli odnośnik prowadzi do nowej karty lub nowego okna. Umieść taką informację bezpośrednio w opisie linku lub w atrybucie aria-label
.
Pamiętaj również, aby odpowiednio opisać odnośniki do plików (np. PDF albo video). Informację o typie pliku (i rozmiarze – jeśli plik jest duży) umieść bezpośrednio w nazwie linku, nie ukrywaj jej w atrybucie aria-label
. Będzie ona istotna w szczególności dla użytkowników korzystających z urządzeń mobilnych. Mało tego – w przypadku plików dobrze jest korzystać z atrybutu download
, który otworzy natywne okno pobierania pliku. Dla przykładu:
<a href="wyniki.pdf" download>Wyniki konkursu (PDF, 240 MB)</a>
2. Powiadomienia… lub ich nieoczekiwany brak.
Użytkownicy korzystający z czytników ekranu muszą zostać poinformowani w momencie, kiedy treść na stronie się zmienia (np. jest dynamicznie ładowana). Niestety, czytnik ich nie powiadomi o zmianach leżących poza obrębem jego punktu uwagi bez delikatnej programistycznej ingerencji – zastosowaniu ARIA Live Regions (regionów na żywo – wiem, brzmi paskudnie).
aria-live
Aby zdefiniować region, należy korzystać z atrybutu aria-live
. Może on przyjmować 3 wartości:
off
– wartość domyślna – zmiany w regionie nie są prezentowane użytkownikowi (chyba, że region leży w obrębie punktu uwagi czytnika)polite
– nowa treść zostanie odczytana dopiero zakończeniu odczytywania bieżącej treści przez czytnikassertive
– nowa treść zostanie odczytana natychmiastowo
aria-atomic
Kolejnym przydatnym atrybutem na drodze do zdefiniowania regionu jest aria-atomic
, który służy do sterowania zakresem odczytywanej treści. Przyjmuje on 2 wartości:
false
– wartość domyślna – czytnik odczytuje jedynie element, w którym nastąpiły zmianytrue
– czytnik odczytuje cały region, w którym nastąpiła zmiana
Dla przykładu (prosto od kolegi Paula) mamy formularz, a w nim pole tekstowe z ograniczoną ilością znaków oraz informację o ilości pozostałych znaków do wpisania.
Oto komunikat, który będzie informował użytkownika jedynie o zmieniającej się ilości dostępnych znaków (czytając kolejno: 280, 279, …):
<span aria-live="polite" aria-atomic="false">Pozostało znaków: <span id="chars2">280</span></span>
Z kolei poniższy komunikat przy każdej zmianie będzie odczytywał zarówno opis, jak i zmieniającą się ilość dostępnych znaków (Pozostało znaków 280, Pozostało znaków 279, …):
<span aria-live="polite" aria-atomic="true">Pozostało znaków: <span id="chars2">280</span></span>
Dla jasności możesz zapoznać się z filmikiem prezentującym powyższy przykład w praktyce.
Role
Regiony to potężne narzędzie. Jednak rekomenduje się, aby zamiast nich korzystać z tzw. ról (jeśli tylko znajdujemy odpowiednią rolę dla naszego przypadku).
Oto role, za pomocą których możemy zdefiniować regiony na żywo:
alert
wartości domyślne:aria-live="assertive"
orazaria-atomic=true
status
wartości domyślne:aria-live="polite"
orazaria-atomic=true
timer
wartość domyślna:aria-live="off"
marquee
wartość domyślna:aria-live="off"
log
wartość domyślna:aria-live="polite"
progressbar
Wydaje mi się, że ich przeznaczenia nie muszę tłumaczyć. Być może marquee brzmi dla Ciebie tajemniczo (dla mnie brzmiało). Jeśli chcesz poznać konkretne przypadku użycia powyższych ról, zachęcam Ciebie to zapoznania się z wyjaśnieniem ról według MDN.
Omówmy sobie podstawowy przykład zastosowania najczęściej wykorzystywanej roli – status
.
Załóżmy, że posiadasz formularz z danymi profilowymi, który edytujesz. Po zmianie pola i kliknięciu na „zapisz” dostajesz informację zwrotną o sukcesie lub błędzie procesu. Aby czytnik przeczytał ją użytkownikowi, należy dodać role="status"
do informacji ze statusem edycji danych.
<div class="message" role="status">Zapisano zmiany!</div>
Rozumiem, że temat regionów na żywo może wydawać się przytłaczający. Pamiętaj jednak o magicznym dokumencie – WAI-ARIA Authoring Practices, który zawiera obszerny opis najlepszych praktyk tworzenia dostępnych stron internetowych. Znajdziesz tam przykłady dla konkretnych komponentów, wyjaśnienie najbardziej spornych przypadków i wiele innych.
Masz już dość tych powiadomień? Wybacz, ale nie mogę pominąć jeszcze jednej, krótkiej uwagi…
UX chciał, programista zrobił…
Kojarzysz powiadomienia, które same, automagicznie giną, np. po 5 sekundach…? Unikaj takich praktyk. Powiadomienie może zniknąć za szybko i wtedy albo zostanie odczytane częściowo, albo w ogóle nie zostanie odczytane.
3. Definicja języka… lub jej brak.
Last but not least. Definiuj odpowiedni język dokumentu. Z pozoru banalna, jednak niesamowicie istotna sprawa (w sumie nie tylko ze względu na dostępność, ale też SEO).
<html lang="pl">
Jeśli zapomnisz o tym atrybucie, czytnik ekranu nie będzie wiedział, z jakiej biblioteki językowej skorzystać. Założy, że chcesz odczytywać stronę w języku, który podałeś podczas konfiguracji czytnika. Cóż, nie zawsze może to być najszczęśliwszy wybór.
Przy okazji podrzucam Tobie świetny przewodnik o tym, jak wybrać odpowiedni język.
Jeśli strona zawiera treść w języku innym niż zadeklarowany w całym dokumencie – dodaj atrybut lang
do elementu zawierającego tą treść.
<p>Oto wyniki konkursu na najlepszą <span lang="fr">jeu de plateau</span>!</p>
A jeśli nadal nie jesteś przekonany, jak bardzo istotny jest wybór odpowiedniego języka – dla rozrywki sprawdź ten filmik.
Na dziś koniec. Jeszcze raz przypominam o pierwszej części oraz drugiej części tego cyklu artykułów. I na koniec dodam, że dobrze było tu wrócić. Ten artykuł powstał w 432564 interwałach pracy, zajadanych krokietami o wstydliwych, nocnych godzinach. Pomimo ogromnych wyrzutów sumienia (ze względu na te krokiety…) – tak dobrze mi było do Ciebie pisać!