RTV EURO AGD to jedna z najstarszych, jeśli nie najstarsza sieć sklepów z elektroniką i sprzętem gospodarstwa domowego działająca w Polsce. Jeśli urodziliście się w latach osiemdziesiątych lub dziewięćdziesiątych, to całkiem możliwe, że swoją pierwszą elektronikę kupowaliście w tym właśnie sklepie. To z tego sklepu pochodzi moja pierwsza wieża stereo, mój pierwszy walkman, a nawet pierwszy „duży” telewizor, który stanął w moim rodzinnym domu. To znaczy, był duży jak na tamte czasy, dzisiaj 25 cali nie robi już na nikim wrażenia, a za kilka lat pewnie mało kto będzie pamiętał, że kiedyś wszystkie telewizory i monitory komputerowe były w formacie 4:3.
W niniejszym artykule przyjrzymy się dostępności strony internetowej www.euro.com.pl z perspektywy osoby niewidomej.
Dla uproszczenia załóżmy, że chcemy dokonać zakupu pralki. Jak wspomnieliśmy w osobnym artykule, osoby niewidome korzystają z komputera nieco inaczej niż osoby widzące. Nie możemy w prosty sposób przewinąć strony, aby dostać się do interesującego nas fragmentu. Możemy za to przeskakiwać po nagłówkach, dlatego należy pochwalić twórców strony euro.com.pl, że po przejściu do wybranej kategorii produktów, nazwy poszczególnych modeli pralek mają postać nagłówków drugiego poziomu (znacznik h2 w kodzie strony). Dzięki temu, naciskając klawisz H na klawiaturze, możemy przeskoczyć od jednego do następnego modelu pralki, tym samym pomijamy skrócony opis parametrów, cenę czy opcję dodania produktu do porównania.
Problemy pojawiają się w momencie, gdy chcemy zawęzić listę produktów do modeli o określonej pojemności lub sposobie załadunku. Nie da się, niestety, szybko przeskoczyć do określonego rodzaju filtru, ponieważ kategorie filtrów (Cena, Raty, Marka itd.) nie zostały oznaczone w kodzie strony jako nagłówki. Kolejny problem dotyczy samych filtrów. Każdy filtr (np. Raty do 50×0% w kategorii „Raty”) to pole wyboru, które można zaznaczyć. Jako osoby niewidome nie wiemy, że jest to pole wyboru ani czy jest ono zaznaczone czy odznaczone. Dzieje się tak, ponieważ kod strony został przygotowany w taki sposób, że informacja o polu wyboru jest ukrywana przed czytnikiem ekranu.
Za wyświetlanie pola wyboru odpowiada następujący kod HTML:
<input type=”checkbox” id=”unikalny_identyfikator” class=”js-filter-checkbox”>
Tworzy on kwadracik, który można zaznaczyć zarówno za pomocą myszki, jak i klawisza spacji. Dla wielu twórców stron internetowych taki kwadracik jest nieatrakcyjny wizualnie, dlatego ukrywają go za pomocą kodu CSS i zamiast niego wstawiają coś własnego. Za ukrycie domyślnego kwadracika odpowiada następująca reguła w kodzie CSS strony:
.checkbox-css input[type=”checkbox”] {
display: none;
}
Wiersz zakończony średnikiem to w kodzie CSS tak zwana deklaracja. Pokazana powyżej deklaracja przekazuje do przeglądarki internetowej informację, że pole wyboru ma nie być wyświetlane. A przynajmniej to standardowe pole wyboru, generowane przez znacznik input. Zamiast tego twórca strony internetowej umieścił w kodzie strony następujący wiersz:
<i></i>
A następnie sprawił za pomocą kodu CSS, że wygląda jak pole wyboru. Rzecz w tym, że znacznik „i” odpowiada w kodzie HTML za wyświetlanie tekstu kursywą. Tym samym ani przeglądarka internetowa, ani czytnik ekranu nie wiedzą, że jest to pole wyboru.
Jak rozwiązać ten problem? Najlepiej byłoby nie wstawiać w kodzie HTML znacznika „i”, a zamiast tego zmienić kod reguły CSS
.checkbox-css input[type=”checkbox”]
w taki sposób, aby pole wyboru miało wygląd zgodny z życzeniem twórcy strony. Można też iść na skróty i zmienić deklarację
display: none;
na
opacity: 0;
Taki kod zadziała, ponieważ deklaracje „display: none” oraz „visibility: hidden” ukrywają dany fragment strony razem z przypisaną mu funkcjonalnością, a deklaracja „opacity: 0” zamiast ukrywać ustawia przezroczystość. W tym konkretnym przypadku jest to przezroczystość 100%.
Innym problemem związanym z filtrowaniem produktów jest to, że poszczególne kategorie filtrów można zwijać, a tym samym ukryć zawarte w danej kategorii filtry. Osoba widząca widzi przed nazwą filtra strzałkę, która sugeruje, że zawartość poniżej jest zwinięta lub rozwinięta. Odpowiada za to poniższy kod CSS:
#filter-box .filter-name::before {
border-left: 6px solid transparent;
border-right: 6px solid transparent;
border-top: 8px solid #999;
}
Osoba niewidoma niestety nie otrzymuje tej samej informacji. Jak więc można to naprawić? Nie ma w kodzie HTML atrybutu, który przekazywałby do przeglądarki internetowej informację o zwinięciu lub rozwinięciu jakiegoś elementu. Na szczęście można tu wykorzystać WAI-ARIA, czyli zestaw atrybutów, który powstał specjalnie po to, aby przekazywać dodatkowe informacje do czytników ekranu. Przygotowaliśmy osobny artykuł, w którym bardziej szczegółowo opisujemy, czym jest WAI-ARIA i co daje osobom niewidomym. Do przekazania stanu rozwijalnego elementu służy atrybut aria-expanded. Może on przyjąć jedną z dwóch wartości: „true”, czyli prawda, lub „false”, czyli fałsz. Należy jednak pamiętać, że nie wystarczy dodać samo aria-expanded=”true”, aby ten kod zadziałał. Zgodnie ze specyfikacją WAI-ARIA, atrybutu aria-expanded można użyć jedynie w przypadku następujących ról: button, combobox, document, link, section, sectionhead oraz window. Innymi słowy, konieczne jest dodanie dwóch atrybutów. Tym samym kod rozwiniętej kategorii filtrów powinien wyglądać następująco (przykład dotyczy kategorii „Marka”):
<div class=”filter filter-brand filter-expanded” data-name=”_” data-group=”brand” data-expanded=”true” aria-expanded=”true” role=”button”>
A kod zwiniętej kategorii filtrów powinien wyglądać następująco:
<div class=”filter filter-brand” data-name=”_” data-group=”brand” data-expanded=”false” aria-expanded=”false” role=”button”>
Gdy już zdecydujemy się na konkretny model pralki i przejdziemy do strony produktu, pojawiają się dwa kolejne problemy. Pierwszy dotyczy wyboru dodatkowej gwarancji. Tuż za ceną produktu znajdują się trzy przyciski wyboru dodatkowej gwarancji: Bez dodatkowej gwarancji, Wariant pełny do 5 lat oraz Wariant podstawowy do 5 lat. Osoby widzące po wybraniu opcji gwarancji widzą obramowanie wokół danego przycisku. Odpowiada za to następująca reguła CSS:
.warranties-section .no-warranty-selector.is-active, .warranties-section .no-warranty-selector:hover, .warranties-section .warranty-box.is-active, .warranties-section .warranty-box:hover {
border-color: #005ca9;
box-shadow: none;
}
Szczególnie istotna jest deklaracja border-color, która dodaje obramowanie w określonym kolorze. Po wpisaniu tego koloru w Google okazuje się, że (według strony colorhexa.com) w przestrzeni barw RGB (Red Green Blue, czyli czerwony, zielony, niebieski) składa się on z 0% koloru czerwonego, 36.1% koloru zielonego oraz 66.3% koloru niebieskiego. Gdyby chcieć zapisać ten kolor w składni RGB, gdzie każdy kolor może przyjąć wartość od 0 do 255, byłoby to „rgb(0,92,169)”. Strona colorhexa oznacza ten kolor jako Dark blue, czyli ciemny niebieski. Problem w tym, że nie ma w tym miejscu żadnej informacji dla osoby niewidomej, która opcja dodatkowej gwarancji została wybrana. Da się to ocenić jedynie poprzez analizę kodu źródłowego strony, a konkretnie poprzez sprawdzenie, że zaznaczony przycisk ma ustawiony styl CSS (a właściwie klasę) „is-active” (jest aktywny).
A więc, jak rozwiązać ten problem? Najlepszym rozwiązaniem byłaby zmiana znacznika HTML tych przycisków i zastąpienie znacznika button znacznikiem input type=”radio”. W ten sposób przeglądarka internetowa przekaże do czytnika ekranu (takiego jak NVDA) informację, że znajdują się tam trzy pola wyboru oraz które pole jest obecnie zaznaczone. Można jednak pójść na skróty i dodać do znacznika button atrybuty WAI-ARIA aria-pressed. Zaznaczony przycisk miałby wartość aria-pressed=”true”, a odznaczony aria-pressed=”false”. Mogłoby to wyglądać następująco:
<button type=”button” class=”no-warranty-selector js-select-no-warranty is-active” aria-pressed=”true”>
Bez dodatkowej ochrony
Oczywiście jest to tylko przykład dla zaznaczonego przycisku, ale reszty łatwo można się domyślić. A co z drugim problemem?
Otóż jest on związany z dodatkowymi opcjami transportu, takimi jak wniesienie urządzenia do mieszkania/domu, czy wniesienie, zdjęcie blokad i wypoziomowanie. Występuje tu identyczny problem, co w przypadku filtrów produktów. Dotyczy on ukrytego pola wyboru i można go rozwiązać w taki sam sposób, jak zostało to opisane wcześniej.
Ostatnie dwa problemy pojawiają się po przejściu do koszyka. Pierwszy związany jest ze wskaźnikiem postępu procesu zamówienia. W ostatnich latach tego typu wskaźniki stały się bardzo popularne. Można je zaobserwować zarówno na stronach sklepów internetowych, gdzie wskazują postęp składania zamówienia, jak i na stronach banków, gdzie wskazują postęp aktualizacji danych, np. dowodu osobistego. Strona euro.com.pl jest przykładem tego pierwszego rodzaju strony. Wskaźnik postępu został tu podzielony na cztery kroki: pierwszy to „Zawartość koszyka”, drugi to „Logowanie i rejestracja”, trzeci to „Dane zamawiającego”, a ostatni, czwarty, to „Sposób płatności”. Bieżący krok został oznaczony za pomocą klasy active. Cała reguła w kodzie CSS wygląda w sposób następujący:
.order-path-step.active span {
width: 30px;
height: 30px;
line-height: 30px;
top: -30px;
}
Jak można się domyślić, bieżący krok ma wizualnie inną wielkość niż pozostałe kroki. Niestety, osoby niewidome nie otrzymują podobnej informacji. Jak więc można to naprawić? Wśród atrybutów WAI-ARIA znajduje się coś odpowiedniego na tę okazję. Tym czymś jest atrybut aria-curent. Jak można przeczytać ze specyfikacji WAI-ARIA, atrybut aria-current może przyjąć jedną z pięciu właściwości: page (strona), step (krok), location (lokalizacja), date (data) oraz time (czas). Specyfikacja dopuszcza również użycie właściwości ”true” w sytuacji, gdy żadne z wymienionych wcześniej oznaczeń nie wydaje się być odpowiednie. Czytnik ekranu wymówi wtedy „bieżący”. Odpowiednią właściwością w tym konkretnym przypadku będzie oczywiście step, czyli krok. Czytnik ekranu wymówi w takiej sytuacji „bieżący krok”. Można to oznaczyć w kodzie HTML w przykładowy sposób:
<div class=”order-path-step active” aria-current=”step”>
1
<div class=”text”>Zawartość koszyka</div>
Ostatni problem można podzielić na dwa podpunkty. Obydwa są związane z tym, jak dany produkt jest wyświetlany na liście produktów w koszyku. Jeśli dany produkt ma obniżoną cenę, stara cena jest przekreślona. Świadczy o tym następujący znacznik oraz reguła w kodzie CSS:
Kod HTML:
<div class=”f11 oldprice c999 tcenter selenium-product-old-price”>
2 199 zł
Reguła CSS:
.oldprice {
font-size: 13px;
text-decoration: line-through;
}
Deklaracja „text-decoration: line-through” oznacza właśnie przekreślenie. Problem w tym, że coś takiego nie jest przekazywane jako przekreślenie do czytnika ekranu. Jak to naprawić?
Jest jeden znacznik w kodzie HTML, który odpowiada za przekreślenie, a właściwie za usunięcie. Jest nim znacznik „del”. A więc należałoby zamienić znacznik div na znacznik del, tak aby kod HTML wyglądał w następujący sposób:
<del class=”f11 oldprice c999 tcenter selenium-product-old-price”>
2 199 zł
</del>
Czy da się w tej sytuacji pójść na skróty? Niestety, nie. Nie ma wśród atrybutów WAI-ARIA takiego, który pełniłby funkcję odpowiadającą znacznikowi „del”. Wydawać by się mogło, że sprawdzi się tutaj dość uniwersalny atrybut „aria-label”, jednak nasze testy pokazują, że w tym konkretnym przypadku on po prostu nie działa. Zgodnie z opisem podanym na Mozilla Developer Network, atrybutu aria-label można używać jedynie w przypadku znaczników interaktywnych (takich jak button, input, textarea, select oraz a href), punktów orientacyjnych (landmark) oraz znaczników, które posiadają rolę widżetu. Specyfikacja WAI-ARIA określa, co jest widżetem. W tym konkretnym przypadku znacznik div nie posiada roli widżetu, a więc nie można tutaj zastosować atrybutu aria-label.
Kolejnym problemem jest to, jak zostało oznaczone usuwanie produktu z koszyka. Jeszcze kilka tygodni temu znajdowała się w tym miejscu ikonka prezentująca kosz na śmieci. Nie posiadała ona żadnej etykiety tekstowej, a więc osoba niewidoma nie wiedziała, że ta ikonka odpowiada za usunięcie produktu z koszyka. Obecnie znajduje się w tym miejscu literka „x”, a lista produktów w koszyku ma postać tabeli. Są więc kolumny i wiersze, a kolumna, w której znajduje się przycisk „x” została oznaczona jako „usuń”. Czytnik ekranu wymawia w tym przypadku „usuń kolumna cztery link x”. Pozwala to domyślić się, że dany link odpowiada za usunięcie produktu, niemniej jednak nie jest to idealne rozwiązanie. Naszym zdaniem warto byłoby tu zastosować atrybut aria-label (jest to możliwe, ponieważ mamy tu do czynienia z interaktywnym znacznikiem a href). Ostateczny kod tego fragmentu strony mógłby wyglądać w następujący sposób:
<td class=”last”>
<a href=”javascript:void(0);” class=”m0a delete js-remove-product” title=”usuń” onclick=”deleteProduct(23087324, this);” data-product-plu=”1244493″ aria-label=”Usuń z koszyka”></a>
</td>
Oczywiście to nie są wszystkie problemy związane z dostępnością, które występują na stronie euro.com.pl. Naszym zadaniem nie było przeprowadzenie audytu dostępności strony. Chodziło nam jedynie o to, aby zaprezentować najistotniejsze z punktu widzenia osoby niewidomej problemy, które istotnie utrudniają, a mniej doświadczonym niewidomym użytkownikom uniemożliwiają zrobienie zakupów na tej stronie. Przy okazji pokazaliśmy dwa mniej istotne problemy (cena oraz postęp zakupów). Zrobiliśmy to, ponieważ uznaliśmy je za dobre przykłady wykorzystania atrybutów WAI-ARIA. Liczymy na to, że ten artykuł trafi do osób odpowiedzialnych za stronę internetową sklepu RTV EURO AGD i że spowoduje to poprawę dostępności tej strony dla osób niewidomych.