Kryteria sukcesu WCAG · Level A

WCAG 3.3.2: Etykiety lub instrukcje

WCAG 3.3.2 wymaga, aby etykiety lub instrukcje były dostarczane, gdy treść wymaga wprowadzenia danych przez użytkownika, zapewniając, że wszyscy użytkownicy — niezależnie od swoich możliwości — mogą zrozumieć, czego się od nich oczekuje przed przesłaniem danych formularza. Brak etykietowania pól formularza jest jedną z najczęstszych i najbardziej wpływowych barier dostępności w sieci.

Co oznacza ta zasada

Kryterium sukcesu WCAG 3.3.2 — Etykiety lub instrukcje (poziom A) stanowi: „Etykiety lub instrukcje są zapewnione, gdy treść wymaga wprowadzania danych przez użytkownika.” W praktyce oznacza to, że każde pole formularza, kontrolka wejściowa, obszar tekstowy i element select, które proszą użytkownika o wprowadzenie lub wybranie informacji, muszą mieć widoczną, znaczącą etykietę lub zestaw instrukcji, które jasno określają cel pola, zanim użytkownik zacznie z nim wchodzić w interakcję.

Kryterium jest celowo szerokie. Obejmuje każdy mechanizm, za pomocą którego użytkownik przekazuje dane: elementy <input> wszystkich typów (text, email, password, number, date, checkbox, radio, file upload), elementy <textarea> dla tekstu wielowierszowego oraz rozwijane listy <select>. Ma również zastosowanie do niestandardowych kontrolek interaktywnych zbudowanych z użyciem ról ARIA, takich jak role='combobox' czy role='listbox'.

Etykieta może być zapewniona na kilka sposobów spełniających to kryterium. Najbardziej niezawodna jest programistycznie powiązana etykieta <label>, która jest widoczna wizualnie i połączona z kontrolką poprzez pasującą parę for/id. Alternatywnie widoczny tekst etykiety można powiązać za pomocą aria-labelledby wskazującego na istniejący element, a uzupełniające instrukcje można połączyć z aria-describedby. Kluczowym wymaganiem jest, aby etykieta lub instrukcja była zapewniona — musi istnieć w formie, którą użytkownik może odebrać. Sam tekst zastępczy (placeholder) nie spełnia tego kryterium, ponieważ znika, gdy tylko użytkownik zaczyna pisać, i nie jest w sposób niezawodny przekazywany przez wszystkie technologie asystujące jako trwała etykieta.

Spełnienie kryterium wymaga, aby każde pole wejściowe miało etykietę, która jest widoczna (lub co najmniej możliwa do określenia programistycznie), dostępna zanim użytkownik zobowiąże się do wypełnienia pola oraz na tyle opisowa, by przekazać, jakich danych się oczekuje. Niespełnienie ma miejsce, gdy pole nie ma żadnej etykiety, gdy jedyną etykietą jest atrybut placeholder, gdy etykieta jest widoczna wizualnie, ale nie jest powiązana programistycznie, lub gdy całkowicie brakuje instrukcji dotyczących wymaganego formatu (np. „Wpisz datę w formacie DD/MM/RRRR”).

WCAG przewiduje wątek wyjątek: gdy formularz zawiera jedno, oczywiste pole — na przykład ogólny pasek wyszukiwania w serwisie z wyraźnie oznaczonym przyciskiem wysyłania tuż obok — sam kontekst może dostarczać wystarczających instrukcji. Jednak ten wyjątek jest bardzo wąski i nie powinien być używany jako ogólne uzasadnienie pomijania etykiet w formularzach z wieloma polami.

Dlaczego to ma znaczenie

Etykiety pól formularzy są pojedynczo najbardziej wpływową funkcją dostępności dla szerokiego spektrum użytkowników. Ich brak tworzy bariery, które mogą uniemożliwić wielu osobom dokończenie transakcji, rejestrację do usług czy skontaktowanie się z organizacją.

Dla osób niewidomych i słabowidzących korzystających z czytników ekranu, pole bez etykiety jest ogłaszane po prostu jako „edit text” lub „blank”, bez kontekstu. Użytkownik nie ma sposobu, by wiedzieć, czy ma wpisać swoje imię i nazwisko, adres e-mail czy numer karty kredytowej. Według Światowej Organizacji Zdrowia około 2,2 miliarda osób na świecie ma jakąś formę upośledzenia wzroku, a miliony z nich używają czytników ekranu jako podstawowego sposobu interakcji z siecią.

Dla użytkowników z niepełnosprawnościami poznawczymi i trudnościami w uczeniu się — w tym dysleksją, ADHD i zaburzeniami pamięci — tekst zastępczy jest szczególnie szkodliwy. Ponieważ placeholder znika przy fokusie lub wprowadzaniu danych, użytkownik, który zatrzyma się w trakcie wypełniania formularza, nie ma odniesienia, czego oczekiwano w polu, które już zaczął wypełniać. Zmusza to go do wyczyszczenia pola, aby ponownie przeczytać instrukcję, co wprowadza zamieszanie i frustrację. Trwałe, widoczne etykiety całkowicie eliminują to obciążenie poznawcze.

Dla użytkowników z niepełnosprawnością ruchową, którzy nawigują za pomocą klawiatury, urządzeń przełączających lub sterowania głosem, etykiety pełnią dodatkową funkcję: dostarczają słów wypowiadanych w celu aktywacji pola przez oprogramowanie do sterowania głosem, takie jak Dragon NaturallySpeaking. Jeśli widoczny tekst etykiety nie odpowiada programistycznej nazwie dostępnej, komenda głosowa kończy się cichą porażką.

Rozważmy konkretny scenariusz z życia: osoba słabowidząca składa wniosek o świadczenie na portalu tureckiej instytucji publicznej. Formularz używa tekstu zastępczego zamiast etykiet. Gdy użytkownik powiększa ekran do 200%, aby go przeczytać, placeholdery znikają, zanim zdąży je odczytać. Użytkownik wypełnia pola, zgadując, i wysyła formularz z błędami, po czym otrzymuje ogólny komunikat o błędzie bez wskazania, które pola są nieprawidłowe. Taki scenariusz skutkuje wykluczeniem z kluczowej usługi publicznej — i jest całkowicie możliwy do uniknięcia.

Poza dostępnością, formularze z etykietami poprawiają SEO, ponieważ roboty wyszukiwarek lepiej rozumieją cel formularza, oraz poprawiają użyteczność dla wszystkich użytkowników, w tym tych na urządzeniach mobilnych, gdzie małe cele dotykowe korzystają z klikalnych obszarów etykiet, które powiększają strefę aktywacji powiązanego pola.

Powiązane reguły Axe-core

  • label — Ta reguła sprawdza, czy każdy element <input> (z wyjątkiem tych z type='hidden', type='image', type='button', type='submit' i type='reset'), każdy <textarea> oraz każdy <select> ma nazwę dostępną. Reguła oznacza elementy, którym brakuje powiązanej etykiety <label>, atrybutu aria-label, odwołania aria-labelledby lub atrybutu title. Jest to główny zautomatyzowany sygnał naruszeń 3.3.2 w standardowych kontrolkach formularzy.
  • select-name — Ta reguła specyficznie dotyczy rozwijanych elementów <select> i weryfikuje, czy mają one niepustą nazwę dostępną. Deweloperzy czasem zakładają, że opcje w rozwijanej liście czynią jej cel oczywistym, ale bez etykiety użytkownicy czytników ekranu słyszą tylko aktualnie wybraną wartość opcji — która może być ogólną wartością domyślną, jak „Select one” — bez wskazania, jaką kategorię wybierają. Axe oznacza elementy <select>, którym brakuje któregokolwiek ze standardowych mechanizmów etykietowania.
  • textarea-label — Ta reguła sprawdza elementy <textarea> pod kątem nazwy dostępnej. Obszary tekstowe wielowierszowe są często używane do komentarzy, wiadomości lub szczegółowego wprowadzania danych, a mimo to często pozostają bez etykiet, w błędnym przekonaniu, że otaczający kontekst jest wystarczający. Axe oznacza każdy <textarea>, którego nie można programistycznie powiązać z etykietą poprzez <label for>, aria-label, aria-labelledby lub title.

Ważne jest zrozumienie ograniczeń testów automatycznych dla tego kryterium. Axe-core może wykryć brak etykiety programistycznej, ale nie jest w stanie określić, czy etykieta, która istnieje, jest faktycznie znacząca lub trafna. Pole oznaczone jako „Field 1” lub etykieta zawierająca jedynie „*” przejdą testy automatyczne, jednocześnie całkowicie zawodząc użytkowników. Zawsze wymagany jest przegląd ręczny, aby potwierdzić, że etykiety jasno opisują oczekiwane dane wejściowe, że instrukcje dotyczące formatu są obecne tam, gdzie są potrzebne (np. formaty dat, wymagania dotyczące haseł) oraz że pola wymagane są zidentyfikowane — najlepiej zarówno wizualnie, jak i programistycznie.

Jak testować

  1. Skan automatyczny za pomocą axe DevTools lub Lighthouse: Otwórz stronę zawierającą formularz w Chrome lub Firefox. Uruchom rozszerzenie przeglądarki axe DevTools i przefiltruj wyniki według reguł label, select-name i textarea-label. Zanotuj każdy oznaczony element. Uruchom Google Lighthouse (audyt Accessibility) jako dodatkową kontrolę. Wyeksportuj lub wykonaj zrzuty ekranu wszystkich naruszeń. Pamiętaj, że czysty raport automatyczny nie gwarantuje zgodności — kontynuuj kroki ręczne.
  2. Inspekcja wizualna: Bez używania jakiejkolwiek technologii asystującej przejrzyj każde pole formularza na stronie. Potwierdź, że każde pole ma widoczną, statyczną etykietę — nie tylko placeholder — umieszczoną wyraźnie w pobliżu pola (zwykle powyżej lub po lewej). Potwierdź, że wymagania dotyczące formatu (np. „Hasło musi mieć co najmniej 8 znaków”) są pokazane przed lub w momencie wprowadzania danych, a nie dopiero po nieudanym wysłaniu. Potwierdź, że pola wymagane są identyfikowane czymś więcej niż samym kolorem.
  3. Test nawigacji klawiaturą: Przechodź przez każde pole formularza za pomocą klawisza Tab. Upewnij się, że gdy każde pole otrzymuje fokus, jego cel jest natychmiast jasny na podstawie widocznej etykiety. Żadne pole nie powinno być osiągalne klawiaturą bez widocznej w tym momencie sąsiadującej, trwałej etykiety.
  4. Test z czytnikiem ekranu NVDA i Firefox: Otwórz formularz z uruchomionym NVDA. Naciskaj Tab, aby przechodzić przez każdą kontrolkę interaktywną. NVDA powinien ogłaszać etykietę, rolę (np. „edit”, „combo box”) oraz stan (np. „required”). Jeśli NVDA ogłasza tylko rolę i stan bez etykiety, pole nie spełnia wymagań. Użyj trybu formularzy NVDA (uruchamianego automatycznie na elementach interaktywnych), aby zasymulować realistyczną nawigację użytkownika.
  5. Test z czytnikiem ekranu VoiceOver i Safari (macOS/iOS): Włącz VoiceOver (Command + F5 na Macu). Używaj Tab lub gestów przesunięcia, aby nawigować do każdego pola formularza. VoiceOver powinien ogłaszać etykietę przed rolą. Na iOS stuknij każde pole i potwierdź, że etykieta jest odczytywana na głos, zanim pojawi się klawiatura. Pola z samym placeholderem są zwykle odczytywane jako placeholder przy pierwszym fokusie, ale staną się „ciche” po wprowadzeniu tekstu.
  6. Test z czytnikiem ekranu JAWS i Chrome: Uruchom JAWS i nawiguj po formularzu za pomocą Tab. Użyj trybu Forms Mode JAWS. Potwierdź, że ogłaszana nazwa każdego pola dokładnie odpowiada jego widocznej etykiecie. Użyj Insert + F1 (pomoc dla pola) w JAWS, aby sprawdzić dodatkowe opisy poprzez aria-describedby.
  7. Test sterowania głosem z Dragon NaturallySpeaking: Aktywuj Dragon i spróbuj wchodzić w interakcję z każdym polem, wypowiadając jego widoczną etykietę. Jeśli wypowiedziana etykieta nie odpowiada programistycznej nazwie dostępnej, pole nie zareaguje na komendę głosową, co wskazuje na niezgodność naruszającą zarówno 3.3.2, jak i powiązane kryteria.

Jak naprawić

Brak etykiety dla pola tekstowego — niepoprawne

<!-- No label provided; placeholder is the only hint -->
<input type='text' name='email' placeholder='Email address' />

Brak etykiety dla pola tekstowego — poprawne

<!-- Visible <label> associated via matching for/id attributes.
     Placeholder may still be used as supplementary hint,
     but the label is the primary, persistent identifier. -->
<label for='email'>Email address</label>
<input type='text' id='email' name='email' placeholder='[email protected]' />

Nieoznaczona lista rozwijana select — niepoprawne

<!-- No label; screen readers will only announce the selected option value -->
<select name='city'>
  <option value=''>Select a city</option>
  <option value='istanbul'>Istanbul</option>
  <option value='ankara'>Ankara</option>
</select>

Nieoznaczona lista rozwijana select — poprawne

<!-- Programmatically associated label makes the field's purpose clear
     before the user opens the dropdown. -->
<label for='city'>City</label>
<select id='city' name='city'>
  <option value=''>Select a city</option>
  <option value='istanbul'>Istanbul</option>
  <option value='ankara'>Ankara</option>
</select>

Textarea bez etykiety — niepoprawne

<!-- The textarea has no label; surrounding paragraph text is not
     programmatically associated and will not be read by screen readers
     as the field's label. -->
<p>Please describe your issue:</p>
<textarea name='message' rows='5'></textarea>

Textarea bez etykiety — poprawne

<!-- Using aria-labelledby to associate the existing visible heading
     with the textarea, or alternatively wrapping with a <label> element. -->
<label for='message'>Please describe your issue</label>
<textarea id='message' name='message' rows='5'></textarea>

Brak instrukcji formatu dla pola daty — niepoprawne

<!-- Label present but no instruction about expected date format;
     users must guess whether to enter 01/06/2025 or 2025-06-01. -->
<label for='dob'>Date of birth</label>
<input type='text' id='dob' name='dob' />

Instrukcje formatu dla pola daty — poprawne

<!-- Format instruction is visible and linked via aria-describedby
     so screen readers announce it when the field receives focus. -->
<label for='dob'>Date of birth</label>
<span id='dob-hint'>Enter as DD/MM/YYYY, e.g. 15/06/1990</span>
<input type='text' id='dob' name='dob' aria-describedby='dob-hint' />

Typowe błędy

  • Używanie placeholder jako jedynej etykiety: Tekst zastępczy znika po wprowadzeniu danych, nie jest niezawodnie ogłaszany jako etykieta przez wszystkie czytniki ekranu i zawodzi użytkowników z niepełnosprawnościami poznawczymi, którzy potrzebują trwałego tekstu odniesienia. Zawsze zapewnij widoczną etykietę <label> oprócz dowolnego placeholdera.
  • Wizualne umieszczanie etykiety w pobliżu pola bez powiązania programistycznego: Element <p> lub <span> umieszczony wizualnie nad polem wygląda jak etykieta dla użytkowników widzących, ale jest ignorowany przez czytniki ekranu. Użyj <label for='id'>, aria-labelledby lub owiń pole wewnątrz elementu <label>.
  • Używanie aria-label z tekstem, który nie odpowiada widocznej etykiecie: Gdy programistyczna nazwa dostępna różni się od widocznego tekstu, użytkownicy sterowania głosem nie mogą aktywować pola, wypowiadając to, co widzą na ekranie, co narusza SC 2.5.3 (Label in Name) oraz tworzy zamieszanie dla użytkowników czytników ekranu.
  • Etykietowanie grupy przycisków radiowych bez podania legendy grupy: Poszczególne przyciski radiowe mogą być oznaczone tekstem swoich opcji, ale jeśli nadrzędne pytanie (np. „Payment method”) nie jest podane za pomocą <fieldset> i <legend>, użytkownicy nawigujący klawiaturą słyszą każdą opcję w oderwaniu, nie rozumiejąc, między czym wybierają.
  • Oznaczanie pól wymaganych wyłącznie kolorem lub gwiazdką bez wyjaśnienia: Gwiazdka (*) obok etykiety nie przekazuje nic użytkownikom czytników ekranu, chyba że jej znaczenie zostanie wyjaśnione (np. notatką na górze formularza „Pola oznaczone * są wymagane”) oraz pola wymagane mają również atrybut required lub aria-required='true'.
  • Pomijanie instrukcji formatu aż do momentu nieudanego wysłania: Pokazywanie zasad dotyczących haseł lub wymagań formatu dat dopiero w komunikatach o błędach po wysłaniu zmusza użytkowników do popełnienia błędu, zanim dowiedzą się, czego się od nich oczekuje. Instrukcje muszą być obecne przed lub w momencie, gdy użytkownik wchodzi w interakcję z polem.
  • Ukrywanie etykiet za pomocą display:none lub visibility:hidden: Te właściwości CSS całkowicie usuwają etykiety z drzewa dostępności. Jeśli etykieta musi być ukryta wizualnie (np. dla minimalistycznego projektu), użyj klasy CSS typu „visually-hidden”, która pozostawia element w drzewie dostępności, jednocześnie przenosząc go poza ekran.
  • Używanie atrybutu title jako jedynej etykiety i zakładanie, że to wystarczy: Choć axe-core może nie oznaczyć etykiety opartej wyłącznie na title, atrybut title pojawia się tylko jako podpowiedź przy najechaniu kursorem i jest niedostępny dla użytkowników korzystających wyłącznie z klawiatury oraz użytkowników mobilnych. Powinien być używany jako opis uzupełniający, a nie główna etykieta.
  • Stosowanie pojedynczego aria-label do kontenera <div> i oczekiwanie, że oznaczy on pola potomne: Etykiety ARIA na elementach kontenerowych nie są dziedziczone przez ich podrzędne kontrolki formularza. Każda kontrolka interaktywna musi być oznaczona indywidualnie.
  • Brak ponownego powiązania etykiet po dynamicznych aktualizacjach treści: Gdy pola formularza są wstrzykiwane dynamicznie za pomocą JavaScript (np. dodawanie wiersza adresu), nowo wstawione pola często nie mają powiązanych etykiet, ponieważ deweloper dodał jedynie widoczny tekst etykiety jako element sąsiedni, bez właściwego powiązania for/id.

Związek z tureckimi regulacjami dotyczącymi dostępności

Turecka Okrężnica Prezydencka 2025/10, opublikowana w Dzienniku Urzędowym nr 32933 w dniu 21 czerwca 2025 r., ustanawia obowiązkowe wymagania dotyczące dostępności stron internetowych, zgodne z WCAG 2.2. Kryterium sukcesu WCAG 3.3.2 — Etykiety lub instrukcje jest wymaganiem poziomu A, co oznacza, że znajduje się na podstawowym poziomie zgodności i jest jednym z najsurowiej egzekwowanych postanowień okólnika.

Okrężnica obejmuje szeroki zakres typów podmiotów, a harmonogramy zgodności różnią się w zależności od sektora. Instytucje publiczne — w tym ministerstwa, gminy, agencje państwowe i organizacje finansowane ze środków publicznych — muszą osiągnąć pełną zgodność z poziomem A w ciągu jednego roku od publikacji okólnika. Podmioty sektora prywatnego objęte zakresem muszą dostosować się w ciągu dwóch lat. Wyraźnie wymienione podmioty sektora prywatnego obejmują platformy e-commerce, banki i instytucje finansowe, szpitale i prywatnych świadczeniodawców opieki zdrowotnej, firmy telekomunikacyjne z 200 000 lub większą liczbą abonentów, biura podróży, prywatne firmy transportowe oraz szkoły prywatne upoważnione przez Ministerstwo Edukacji Narodowej (MoNE).

Dla wszystkich tych podmiotów brak etykiet pól formularzy nie jest jedynie niedociągnięciem w zakresie użyteczności — stanowi bezpośrednią niezgodność regulacyjną. Formularze są wszechobecne we wszystkich objętych usługach cyfrowych: obywatele składają wnioski na portalach rządowych, pacjenci rezerwują wizyty na stronach szpitali, klienci finalizują zakupy na platformach e-commerce, a uczniowie zapisują się przez portale szkolne. Każda z tych ścieżek opiera się na formularzach, a każde pole bez etykiety w tych formularzach jest wykazywalnym naruszeniem WCAG 3.3.2, które audytorzy mogą udokumentować i zgłosić.

Organizacje objęte okólnikiem powinny traktować zgodność z SC 3.3.2 jako warunek wstępny każdego audytu dostępności lub procesu certyfikacji. Ponieważ jest to kryterium poziomu A, nie może być ono uchylone ani odroczone — roszczenia częściowej zgodności, które wyłączają elementy poziomu A, nie są uznawane. Podmioty, które nie mogą wykazać obecności etykiet przy wszystkich swoich formularzach dostępnych publicznie, ryzykują stwierdzenia naruszeń regulacyjnych, publiczne raportowanie niezgodności oraz szkody reputacyjne na rynku, na którym zaufanie do usług cyfrowych jest coraz silniej powiązane z projektowaniem inkluzywnym.

Z praktycznego punktu widzenia osiągnięcie zgodności z 3.3.2 jest jednym z działań o najniższym nakładzie pracy i najwyższym wpływie, jakie organizacja może podjąć. Powiązanie etykiet z istniejącymi kontrolkami formularza zazwyczaj wymaga jedynie drobnych zmian w HTML i nie wpływa na projekt wizualny, jeśli zostanie poprawnie wdrożone. Dla organizacji korzystających z SDK nakładki Accsible, automatyczne wykrywanie brakujących etykiet może ujawniać te naruszenia podczas rutynowego skanowania, dostarczając zespołom deweloperskim praktycznych wskazówek naprawczych przed upływem terminów regulacyjnych.