Dlaczego dostępność formularzy ma znaczenie

Formularze to jeden z najważniejszych elementów interaktywnych na stronach internetowych. Formularz kontaktowy, logowanie, rejestracja, wyszukiwarka — użytkownicy muszą z nimi sprawnie pracować. Problem polega na tym, że wielu deweloperów projektuje formularze wyłącznie z myślą o użytkownikach widzących, zapominając o osobach korzystających z czytników ekranu, nawigacji klawiaturowej czy innych technologii asystujących.

W Polsce około 12% populacji to osoby z niepełnosprawnościami, z czego znaczna część korzysta z technologii asystujących podczas przeglądania internetu. Ustawa o dostępności cyfrowej wymaga, aby strony podmiotów publicznych spełniały standard WCAG 2.1 na poziomie AA. Ale nawet strony komercyjne mają powody, by dbać o dostępność — to po prostu większa grupa potencjalnych klientów.

Podstawy: semantyczny HTML

Zanim sięgniemy po ARIA, upewnijmy się, że fundamenty są solidne. Semantyczny HTML robi większość pracy za nas:

<form>
    <label for="email">Adres e-mail</label>
    <input type="email" id="email" name="email" required>
</form>

Element <label> powiązany z <input> przez atrybut for — to najważniejsza zasada dostępności formularzy. Czytnik ekranu odczyta etykietę, gdy użytkownik skupi się na polu. Bez <label> — pole jest anonimowe, użytkownik nie wie, co wpisać.

Częsty błąd: używanie <div> lub <span> zamiast <label>, albo placeholder jako jedynego opisu pola. Placeholder znika po rozpoczęciu wpisywania — użytkownik traci kontekst.

Kiedy potrzebujemy ARIA

ARIA (Accessible Rich Internet Applications) to zestaw atrybutów HTML rozszerzających informacje przekazywane technologiom asystującym. Złota zasada ARIA brzmi: nie używaj ARIA, jeśli natywny element HTML rozwiązuje problem. Natywny <button> jest lepszy od <div role="button">.

ARIA jest potrzebna, gdy:

  • Interfejs wykracza poza standardowe elementy HTML
  • Trzeba przekazać dodatkowy kontekst lub instrukcje
  • Dynamicznie zmieniana treść wymaga powiadomienia użytkownika
  • Standardowy element nie zapewnia wystarczającej informacji

aria-label i aria-labelledby

aria-label nadaje etykietę elementowi, gdy widoczna etykieta nie istnieje lub nie jest powiązana:

<button aria-label="Zamknij okno dialogowe">
    <svg aria-hidden="true"><!-- ikona X --></svg>
</button>

Przycisk z samą ikoną byłby nieczytelny dla czytnika ekranu. aria-label dostarcza tekstowy opis akcji.

aria-labelledby wskazuje na istniejący element, który pełni rolę etykiety:

<h2 id="contact-heading">Formularz kontaktowy</h2>
<form aria-labelledby="contact-heading">
    <!-- pola formularza -->
</form>

Różnica: aria-label zawiera tekst bezpośrednio, aria-labelledby odwołuje się do innego elementu po ID. aria-labelledby ma wyższy priorytet — jeśli oba są obecne, czytnik użyje aria-labelledby.

aria-describedby — dodatkowe instrukcje

aria-describedby łączy pole z tekstem zawierającym dodatkowe instrukcje lub wyjaśnienia:

<label for="password">Hasło</label>
<input type="password" id="password" aria-describedby="password-help">
<p id="password-help">Minimum 8 znaków, w tym jedna wielka litera i jedna cyfra.</p>

Czytnik ekranu odczyta: "Hasło, pole hasła. Minimum 8 znaków, w tym jedna wielka litera i jedna cyfra." Etykieta jest odczytywana jako pierwsza, opis jako uzupełnienie. To pozwala przekazać wymagania dotyczące pola bez zaśmiecania etykiety.

Można wskazać wiele elementów, oddzielając ID spacjami:

<input type="text" id="iban" aria-describedby="iban-format iban-example">
<p id="iban-format">Format: PL + 26 cyfr</p>
<p id="iban-example">Przykład: PL61109010140000071219812874</p>

Walidacja formularzy i komunikaty błędów

Dostępna walidacja wymaga trzech elementów: wskazania pola z błędem, opisania błędu i powiadomienia użytkownika.

aria-invalid informuje, że wartość pola jest nieprawidłowa:

<input type="email" id="email" aria-invalid="true" aria-describedby="email-error">
<p id="email-error" role="alert">Podaj prawidłowy adres e-mail.</p>

Atrybut aria-invalid="true" sygnalizuje czytnikowi, że pole wymaga poprawy. Element z role="alert" jest automatycznie odczytywany — użytkownik nie musi sam szukać komunikatu błędu.

aria-required oznacza pole wymagane. Choć HTML5 ma atrybut required, aria-required="true" jest przydatne w formularzach z niestandardową walidacją:

<input type="text" id="name" aria-required="true">

Wzorzec walidacji w praktyce:

  1. Przy submit formularza waliduj pola
  2. Ustaw aria-invalid="true" na polach z błędami
  3. Wyświetl komunikaty błędów powiązane przez aria-describedby
  4. Przenieś fokus na pierwsze pole z błędem
  5. Opcjonalnie: wyświetl podsumowanie błędów na górze formularza z role="alert"
function showError(field, message) {
    field.setAttribute('aria-invalid', 'true');
    const errorEl = document.getElementById(field.id + '-error');
    errorEl.textContent = message;
    errorEl.setAttribute('role', 'alert');
}

aria-live — dynamiczne komunikaty

Gdy treść strony zmienia się dynamicznie (bez przeładowania), czytniki ekranu domyślnie tego nie zauważają. aria-live rozwiązuje ten problem:

<div aria-live="polite" id="form-status"></div>

Wartości aria-live:

  • polite — czytnik odczyta zmianę, gdy skończy bieżące zadanie. Odpowiedni dla informacji uzupełniających.
  • assertive — czytnik natychmiast przerwie bieżące odczytywanie i ogłosi zmianę. Używaj oszczędnie — tylko dla krytycznych komunikatów.

Po udanym wysłaniu formularza:

document.getElementById('form-status').textContent = 'Wiadomość została wysłana pomyślnie.';

Czytnik automatycznie odczyta tę treść, bo element ma aria-live="polite".

Nawigacja klawiaturowa

Formularze muszą być w pełni obsługiwalne klawiaturą. Podstawowe zasady:

  • Tab przenosi fokus na kolejne interaktywne elementy
  • Kolejność Tab powinna odpowiadać logicznej kolejności pól (unikaj tabindex > 0)
  • Fokus musi być widoczny — nie usuwaj outline bez dostarczenia alternatywnego wskaźnika fokusa
  • Enter powinien submitować formularz
  • Escape powinien zamykać dropdowny i okna modalne

Częsty błąd: niestandardowe elementy (custom dropdown, date picker) nie obsługują klawiatury. Jeśli tworzysz niestandardowy komponent, musisz zaimplementować pełną obsługę klawiaturową — to obowiązek, nie opcja.

Testowanie dostępności

Żadna ilość atrybutów ARIA nie zastąpi testowania. Narzędzia, których używamy:

  • Lighthouse (Chrome DevTools) — automatyczny audyt dostępności, wykrywa najczęstsze problemy
  • axe DevTools — rozszerzenie przeglądarki z dokładniejszym skanowaniem
  • NVDA (Windows) — darmowy czytnik ekranu do ręcznego testowania
  • VoiceOver (macOS/iOS) — wbudowany czytnik ekranu Apple
  • Nawigacja klawiaturowa — przejdź cały formularz samym Tabem i Enterem

Automatyczne narzędzia wykrywają około 30-40% problemów z dostępnością. Reszta wymaga ręcznego testowania — przejścia formularza z czytnikiem ekranu i samą klawiaturą.

Podsumowanie

Dostępne formularze to nie kwestia dodania kilku atrybutów ARIA — to podejście do projektowania. Zacznij od semantycznego HTML (<label>, <fieldset>, <legend>, poprawne typy <input>). Sięgaj po ARIA, gdy natywne elementy nie wystarczają. Zawsze testuj z czytnikiem ekranu i klawiaturą.

Chcesz poprawić dostępność formularzy na swojej stronie? Skontaktuj się z nami — przeprowadzimy audyt i pomożemy wdrożyć poprawki.