CSStrona główna
Baza dla developera

Techniczne wzorce dostępnych formularzy i przycisków.

Konkretne przykłady kodu do wdrożenia poprawek WCAG: powiązane etykiety, programowe oznaczenie pól wymaganych i dostępne nazwy przycisków z ikoną.

ImplementacjaWCAG 2.2: 1.3.1 Info and Relationships, 3.3.2 Labels or Instructions, 4.1.2 Name, Role, Value

Jak powiązać label z inputem w formularzu?

Każdy natywny input, select i textarea powinien mieć dostępną nazwę wynikającą z widocznej etykiety. Najprostszy i najstabilniejszy mechanizm to label[for] + id.

Kiedy stosować

Stosuj dla pojedynczych pól formularza. Dla grup checkbox/radio używaj dodatkowo fieldset i legend, bo etykieta pojedynczego pola nie opisuje całej grupy.

Wdrożenie

  • Nadaj polu unikalny id w obrębie dokumentu.
  • Ustaw label for na dokładnie tę samą wartość co id pola.
  • W React użyj htmlFor zamiast for.
  • Zostaw placeholder jako przykład formatu, nie jako jedyną etykietę.
Dobry przykładTAK
<label for="email">Adres e-mail</label>
<input id="email" name="email" type="email" autocomplete="email">
AntywzorzecNIE
<span>Adres e-mail</span>
<input name="email" type="email" placeholder="Adres e-mail">

Checklista testowa

  • Kliknięcie etykiety ustawia fokus w polu.
  • Czytnik ekranu odczytuje nazwę pola razem z typem kontrolki.
  • Nie ma zduplikowanych id w formularzu.
  • Test axe nie zgłasza reguł label, label-title-only ani aria-input-field-name dla tego pola.
ImplementacjaWCAG 2.2: 1.3.1 Info and Relationships, 3.3.2 Labels or Instructions, 4.1.2 Name, Role, Value

Jak oznaczyć wymagane pole formularza w HTML?

Wymagalność pola musi być dostępna dla przeglądarki i technologii asystujących, a nie wyłącznie zakodowana kolorem, gwiazdką lub tekstem w projekcie graficznym.

Kiedy stosować

Dla natywnych pól formularza używaj required. Dla niestandardowych komponentów z rolą ARIA dodaj aria-required="true" oraz obsługę walidacji i komunikatu błędu.

Wdrożenie

  • Dodaj required do input, select lub textarea, jeżeli pole jest obowiązkowe.
  • Jeśli gwiazdka jest tylko dekoracją wizualną, oznacz ją aria-hidden="true".
  • Dodaj widoczną informację, które pola są wymagane albo opcjonalne.
  • Po walidacji połącz komunikat błędu z polem przez aria-describedby.
Dobry przykładTAK
<label for="email">
  Adres e-mail <span aria-hidden="true">*</span>
</label>
<input id="email" name="email" type="email" required aria-describedby="email-error">
<p id="email-error">Podaj prawidłowy adres e-mail.</p>
AntywzorzecNIE
<label for="email">Adres e-mail *</label>
<input id="email" name="email" type="email">

Checklista testowa

  • API dostępności pokazuje pole jako wymagane.
  • Walidacja nie opiera się wyłącznie na kolorze lub gwiazdce.
  • Komunikat błędu jest powiązany z konkretnym polem.
  • Dla komponentów customowych wymaganie jest widoczne przez aria-required="true".
ImplementacjaWCAG 2.2: 2.4.6 Headings and Labels, 4.1.2 Name, Role, Value

Jak nadać dostępną nazwę przyciskowi z ikoną?

Przycisk bez widocznego tekstu musi mieć programową nazwę opisującą akcję. Najczęściej wystarczy aria-label na elemencie button.

Kiedy stosować

Stosuj przy ikonach pełniących funkcję przycisku: zamknięcie modala, wyszukiwanie, usuwanie, edycja, menu, koszyk, pokazanie hasła.

Wdrożenie

  • Używaj natywnego button zamiast div/span z onClick.
  • Dodaj aria-label opisujący akcję, np. „Usuń produkt z koszyka”.
  • Oznacz dekoracyjną ikonę jako aria-hidden="true".
  • Jeżeli obok ikony jest widoczny tekst, nazwa dostępna powinna zawierać ten sam tekst.
Dobry przykładTAK
<button type="button" aria-label="Usuń produkt z koszyka">
  <svg aria-hidden="true" focusable="false" viewBox="0 0 24 24">
    <!-- ikona -->
  </svg>
</button>
AntywzorzecNIE
<button type="button">
  <svg viewBox="0 0 24 24">
    <!-- ikona kosza -->
  </svg>
</button>

Checklista testowa

  • Czytnik ekranu odczytuje konkretną akcję przycisku.
  • Przycisk jest dostępny z klawiatury i ma widoczny focus.
  • Ikona dekoracyjna nie jest odczytywana jako osobna treść.
  • Test axe nie zgłasza button-name ani aria-command-name.