Dodajemy formularz kontaktowy 4#
Poprawiamy dostępność formularza
W tym poście zajmuję się dostępnością formularza.
Jeśli trafiłeś tu bezpośrednio, zajrzyj do pierwszego postu, gdzie opisuję założenia i tworzę podstawową strukturę formularza.
- HTML + otwieranie / zamykanie JQuery
- Walidacja HTML5/JS + AJAX
- Walidacja PHP + Swiftmailer
- Dostępność formularza
- Zrefaktoryzowana wersja + Github
Dostępność
Co to jest i dlaczego jest to ważne pisałem już wcześniej.
W kodzie, który stworzyliśmy, mamy już dwa elementy, które wpływają na dostępność. Mowa o:
<label>
- (#musthave) etykieta sprawia, że w większości przypadków, gdy klikniemy na tekst opisujący pole, automatycznie nas do niego przeniesie. Ponadto czytnik ekranowy opisze to pole po uzyskaniu focusu.placeholder="wartość"
- ten atrybut przeważnie też zostanie odczytane przez czytnik ekranowy.
Jest to jednak niewiele. Mamy jeszcze sporo do dodania. Zacznijmy od całego formularza.
role="dialog"
- w naszym przypadku formularz to odseparowane od reszty strony okienko i właśnie rola “dialog” odpowiada takim elementom strony. Dzięki temu czytnik ekranowy poinformuje użytkownika, że otwiera okno dialogowe, które jest odseparowane od reszty strony.aria-label="opis"
- opis, który zostanie odczytany przez technologie wspomagające.aria-hidden="true"
- nasz formularz początkowo jest ukryty. Ten atrybut sprawia, że pozostanie także niewidoczny dla czytników ekranowych. Będziemy zmieniać to pole dynamicznie podczas otwierania/zamykania.
Nasze wnętrze formularza również potrzebuje dodatkowych atrybutów:
aria-live="polite"
- użytkownik, który używa czytnik ekranowy, nie ma pojęcia o kumunikatach, które generujemy. Dzięki temu problem jest rozwiązany. Jest to niezwykle ważny atrybut, gdy tworzymy elementy, które pojawiają sie dynamicznie bez przeładowania strony.title="Opis"
- dzięki temu gdy najedziemy na przycisk zamknięcia, wyświetlony zostanie opis, który informuje za co element jest odpowiedzialny. Również zostanie to przeczytane przez czytnik ekranowy. Bez tego użytkownik z niego korzystający nie miałby pojęcia, od czego jest ten przycisk.
Role=”dialog” oraz to, że stworzyliśmy okno dialogowe, zobowiązuje nas do dodania jeszcze kilku kluczowych funkcjonalności:
- “Zapętlenie focusu” - czyli np. podczas “tabowania” (użytkownicy konsol, tv, czy zdani na klawiatury, którzy nawigują za pomocą “focusu”) nie jest możliwe wyjście poza aktualne okno, czyli:
- Gdy osiągniemy ostatni element (w tym wypadku przycisk zamknięcia) następny jest pierwszy element w oknie
- Gdy z pierwszego elementu będziemy chcieli cofnąć się kombinacją Shift+tab przeskoczy do ostatniego elementu
- Klawisz ESC - umożliwia zamknięcie formularza
- Gdy okno jest otwierane “focus” dostaje pierwszy element
- Gdy okno jest zamykane “focus” uzyskuje przycisk, który je otworzył
Zrealizujmy to:
Zauważ, że aby to zrobić konieczne jest zatrzymanie domyślnego zachowania - preventDefault();
Użytkownik bez Javascript-u
Traktowałbym to raczej jako ciekawostkę, gdyż obecnie strony głównie opierają się na Javascripcie, w tym [moja](https://jaki-jezyk-programowania.pl/) jest od niego uzależniona. Nie potrafię sobie wyobrazić, że ktoś w dzisiejszych czasach nie ma w przeglądarce Javascriptu. Ponadto nasz formularz wykorzystuje reCAPTCHE, która bez JS-a się nie obejdzie. Nie widzę sensu w dbaniu o użytkowników bez JS-a w takim wypadku. Mimo wszystko z punktu widzenia dostępności powinno się to robić.
Gdybyśmy w jakiś sposób zastąpili reCAPTCHE, możliwe jest, aby osoby, które nie używają Javascriptu nadal były w stanie korzystać z formularza.
Możesz to przetestować wyłączając Javascript w przeglądarce. W Chrome to: Opcje -> Ustawienia -> Pokaż ustawienia zaawansowane -> W sekcji Prywatność -> Ustawienia Treści -> Sekcja Javascript lub szybciej, można kliknąć kłodkę obok adresu URL, gdzie znajdziemy tą opcję. Zauważ, że użytkownik bez JS utraci też na dynamicznie generowanych komunikatach i zostanie odniesiony bezpośrednio do pliku emailform.php. Również wykona się domyślna walidacja HTML5. Wcześniej te działania zatrzymaliśmy za pomocą preventDefault();
Polega to na tym, aby formularz wstępnie nie był schowany (display: none), tylko, żeby robił to JS. W efekcie użytkownik bez JS-a zobaczy od razu formularz na widoku i będzie w stanie go użyć. Stworzymy więc sobie klasę pomocniczą, którą później usuniemy JS-em:
no i usunięcie zaraz po odwołaniu do elementu:
Cały kod i efekt końcowy (Spróbuj przejechać się klawiszami i czytnikiem ekranowym po formularzu, aby sprawdzić efekty):