Kryteria sukcesu WCAG · Level A

WCAG 3.3.1: Identyfikacja błędów

WCAG 3.3.1 wymaga, aby gdy błąd wprowadzania zostanie automatycznie wykryty, element zawierający błąd został zidentyfikowany, a sam błąd opisany użytkownikowi w formie tekstowej. Zapewnia to, że osoby z niepełnosprawnościami mogą rozpoznać, zrozumieć i poprawić błędy podczas wypełniania formularzy.

Co Oznacza Ta Zasada

WCAG 3.3.1 Identyfikacja błędu jest kryterium sukcesu na poziomie A w ramach zasady Zrozumiałość. Stanowi: „Jeśli błąd danych wejściowych jest automatycznie wykrywany, element zawierający błąd jest identyfikowany, a błąd jest opisany użytkownikowi w tekście.” W praktyce oznacza to, że za każdym razem, gdy Twoja strona lub aplikacja automatycznie waliduje dane wprowadzane przez użytkownika — przy wysłaniu formularza, przy utracie fokusu z pola lub w czasie rzeczywistym — w przypadku wykrycia błędu muszą zajść dwie rzeczy: konkretne pole lub kontrolka zawierająca błąd musi być wyraźnie zidentyfikowana, a charakter błędu musi zostać zakomunikowany za pomocą rzeczywistej treści tekstowej (nie wyłącznie kolorem, ikoną czy dźwiękiem).

Kryterium ma zastosowanie do każdej sytuacji, w której dane są zbierane od użytkowników i walidacja odbywa się automatycznie. Obejmuje to elementy formularzy HTML, takie jak <input>, <select>, <textarea>, a także niestandardowe interaktywne widżety zbudowane z użyciem ARIA. Obejmuje walidację po stronie klienta wywoływaną przez JavaScript, natywną walidację przeglądarki z użyciem atrybutów takich jak required, pattern, minlength i type, a także wyniki walidacji po stronie serwera renderowane po przeładowaniu strony lub dynamicznie wstrzykiwane do DOM.

Spełnienie wymaga, aby: (1) każde pole z błędem było programowo powiązane z komunikatem o błędzie — zazwyczaj poprzez aria-describedby lub aria-errormessage — tak aby technologie asystujące mogły go odczytać; (2) komunikat o błędzie był zwykłym tekstem widocznym w interfejsie (nie ukrytym przed użytkownikami widzącymi); oraz (3) tekst jasno opisywał, co poszło nie tak, a nie tylko, że coś poszło nie tak. Na przykład „Adres e-mail jest wymagany” jest prawidłowym opisem błędu, podczas gdy wyświetlenie jedynie czerwonej ramki lub ikony wykrzyknika bez tekstowej alternatywy jest niezgodne z wymaganiami.

Niespełnienie występuje, gdy: błędy są sygnalizowane wyłącznie poprzez zmianę koloru (czerwona ramka bez tekstu), błędy są ogłaszane tylko za pomocą role="alert" bez wskazania, które pole jest dotknięte, tekst komunikatu o błędzie jest pusty lub zbyt ogólny (np. „Nieprawidłowe dane”), albo komunikaty o błędach istnieją w DOM, ale nie są programowo powiązane z odpowiednim polem, przez co czytniki ekranu nie mogą ich z nim skojarzyć.

WCAG 3.3.1 nie ma zastosowania, gdy nie zachodzi automatyczne wykrywanie — na przykład jeśli formularz zostanie wysłany, a serwer po prostu przeładuje stronę bez jakiejkolwiek informacji o tym, co poszło nie tak; jest to odrębna wada użyteczności, ale wykracza poza ścisły zakres tego kryterium. Jednak jeśli Twój system wykonuje automatyczne wykrywanie (co dotyczy praktycznie wszystkich współczesnych formularzy), kryterium jest w pełni w zakresie. W samym kryterium nie zdefiniowano żadnych wyjątków dla konkretnych typów danych wejściowych ani przypadków użycia.

Dlaczego To Ma Znaczenie

Identyfikacja błędów bezpośrednio wpływa w istotny sposób na wiele grup osób z niepełnosprawnościami. Dla osób niewidomych i słabowidzących, które polegają na czytnikach ekranu, takich jak NVDA, JAWS czy VoiceOver, czerwona ramka lub ikona ostrzegawcza nie przekazują żadnej informacji. Jeśli komunikat o błędzie nie jest obecny jako rzeczywisty tekst i nie jest programowo powiązany z polem zawierającym błąd, czytnik ekranu go nie odczyta, a użytkownik może wielokrotnie próbować wysłać formularz, nie rozumiejąc, dlaczego próba się nie udaje. Według Światowej Organizacji Zdrowia około 2,2 miliarda ludzi na świecie ma jakąś formę zaburzeń widzenia, a miliony codziennie polegają na technologiach asystujących, aby korzystać z treści internetowych.

Dla użytkowników z niepełnosprawnościami poznawczymi — w tym dysleksją, zaburzeniami uwagi i zaburzeniami pamięci — niejasne komunikaty o błędach, takie jak „Coś poszło nie tak”, tworzą istotne bariery. Osoby te odnoszą ogromne korzyści z precyzyjnych, opisowych komunikatów o błędach, które dokładnie wskazują, które pole wymaga poprawy i jaki powinien być prawidłowy format lub wartość. Na przykład zamiast „Nieprawidłowa data” komunikat „Data urodzenia musi być w formacie DD/MM/RRRR” jest znacznie bardziej użyteczny.

Użytkownicy z niepełnosprawnościami ruchowymi, którzy nawigują za pomocą klawiatury lub urządzeń przełączających, wkładają znaczący wysiłek w poruszanie się po formularzu. Gdy błąd jest niejasny lub niezidentyfikowany, muszą ponownie przechodzić przez cały formularz, aby znaleźć problem, co znacznie zwiększa koszt poznawczy i fizyczny wypełniania formularza. Jasna identyfikacja błędów pozwala tym użytkownikom przejść bezpośrednio do problematycznego pola.

Rozważmy ten scenariusz z życia wzięty: obywatel Turcji próbuje zarejestrować się w rządowym portalu e-usług, aby złożyć wniosek o świadczenie z tytułu niepełnosprawności. Formularz wymaga numeru identyfikacji narodowej w określonym formacie. Użytkownik, który jest niewidomy, wprowadza swój numer. Po wysłaniu formularza strona przeładowuje się z polami podświetlonymi na czerwono, ale bez powiązanego tekstowego komunikatu o błędzie. Czytnik ekranu ponownie odczytuje tylko etykiety pól — użytkownik nie ma pojęcia, co poszło nie tak ani które pole jest problematyczne. Całkowicie porzuca proces, tracąc dostęp do kluczowej usługi publicznej. To dokładnie sytuacja, której WCAG 3.3.1 ma zapobiegać.

Poza dostępnością, jasna identyfikacja błędów poprawia współczynniki konwersji i użyteczność dla wszystkich użytkowników. Badania UX konsekwentnie pokazują, że opisowe komunikaty o błędach wyświetlane inline zmniejszają porzucanie formularzy. Z perspektywy SEO poprawione wskaźniki zaangażowania użytkowników — w tym dłuższy czas spędzony w serwisie i pomyślne wysyłanie formularzy — z czasem pozytywnie wpływają na pozycjonowanie w wyszukiwarkach.

Powiązane Reguły Axe-core

WCAG 3.3.1 wymaga ręcznego testowania dla pełnej weryfikacji. Wynika to z faktu, że narzędzia automatyczne mogą wykryć obecność lub brak określonych wzorców strukturalnych (takich jak aria-describedby lub aria-errormessage), ale nie są w stanie ocenić, czy treść tekstowa komunikatu o błędzie jest sensowna, dokładna lub wystarczająca, aby pomóc użytkownikowi zrozumieć i poprawić błąd. Narzędzie automatyczne widzi, że istnieje element role="alert"; nie może jednak ocenić, czy komunikat „Błąd w wierszu 4” w wystarczający sposób opisuje błąd walidacji dla użytkownika czytnika ekranu.

  • aria-required-attr: Ta reguła axe-core sprawdza, czy elementy z określonymi rolami ARIA mają wszystkie wymagane atrybuty ARIA. Choć nie jest to wyłącznie reguła dotycząca identyfikacji błędów, jest istotna, ponieważ pole formularza w stanie błędu, które używa role="textbox" lub podobnej roli bez wymaganych atrybutów, może nie przekazywać informacji o stanie technologiom asystującym, co podważa komunikację błędów.
  • aria-valid-attr-value: Ta reguła oznacza przypadki, w których atrybuty ARIA odwołują się do identyfikatorów, które nie istnieją w DOM. Na przykład, jeśli pole używa aria-describedby="email-error", ale nie istnieje element z id="email-error", powiązanie jest zerwane i komunikat o błędzie nie zostanie odczytany przez czytniki ekranu. Jest to częsty wzorzec błędu w kontekście 3.3.1.
  • Wymóg oceny ręcznej: Testerzy muszą ręcznie wywołać błędy walidacji, a następnie użyć czytnika ekranu, aby potwierdzić, że: pole z błędem jest identyfikowane po nazwie lub etykiecie, opis błędu jest odczytywany, komunikat jest sensowny i umożliwia działanie oraz że błąd nie jest komunikowany wyłącznie za pomocą środków nietekstowych. Skanowanie automatyczne nie może symulować sekwencji interakcji użytkownika ani ocenić jakości semantycznej tekstu komunikatu, co czyni osąd człowieka niezbędnym dla tego kryterium.

Jak Testować

  1. Automatyczny skan za pomocą axe DevTools lub Lighthouse: Uruchom skan axe DevTools na stronie zawierającej formularz przed i po wywołaniu błędów walidacji. Szukaj w szczególności naruszeń związanych z uszkodzonymi odwołaniami aria-describedby lub aria-errormessage, brakującymi regionami role="alert" lub aria-live używanymi do dynamicznego wstrzykiwania błędów oraz polami formularza bez etykiet (co również uniemożliwia prawidłowe powiązanie błędów). W Lighthouse sprawdź audyt Accessibility pod kątem naruszeń związanych z formularzami. Pamiętaj, że czysty raport z narzędzia automatycznego nie potwierdza zgodności z 3.3.1 — eliminuje jedynie pewne błędy strukturalne.
  2. Ręczny test nawigacji klawiaturą: Używając wyłącznie klawiatury (Tab, Shift+Tab, Enter, Spacja), spróbuj wysłać formularz z celowo nieprawidłowymi lub brakującymi wartościami. Zweryfikuj, że: fokus przechodzi do pierwszego pola z błędem lub w jego pobliże, każdy komunikat o błędzie jest widoczny w obszarze widoku oraz że komunikaty o błędach identyfikują konkretne pole po nazwie i opisują problem zwykłym tekstem.
  3. Test z czytnikiem ekranu NVDA + Firefox: Otwórz formularz w Firefox z aktywnym NVDA. Wyślij formularz z błędami. Uważnie słuchaj: czy NVDA ogłasza, które pole zawiera błąd? Czy opis błędu jest odczytywany na głos? Przejdź tabulatorem do błędnego pola — czy NVDA odczytuje powiązany komunikat o błędzie jako część opisu dostępnego pola? Jeśli używasz regionów aria-live, upewnij się, że komunikat nie jest opóźniony ani pomijany.
  4. Test z czytnikiem ekranu VoiceOver + Safari (macOS/iOS): Powtórz ten sam proces, używając VoiceOver w Safari. Użyj VO+Strzałka w prawo, aby czytać formularz po wysłaniu. Potwierdź, że każde pole z błędem zawiera tekst błędu w swojej dostępnej nazwie lub opisie. Na iOS przetestuj nawigację dotykową i gesty przesuwania.
  5. Test z czytnikiem ekranu JAWS + Chrome: Z uruchomionym JAWS w Chrome wyślij formularz z błędami. Użyj wirtualnego kursora JAWS, aby przejść do każdego pola formularza z błędem. Potwierdź, że tekst komunikatu o błędzie jest uwzględniony w odczycie pola przez JAWS. Sprawdź również zachowanie trybu formularzy JAWS, ponieważ tryb formularzy tłumi niektóre komunikaty z regionów live.
  6. Audyt kolorów i sygnałów nietekstowych: Obejrzyj każdy stan błędu wizualnie. Tymczasowo usuń lub wyłącz CSS (za pomocą narzędzi deweloperskich przeglądarki lub bookmarkletu) i potwierdź, że identyfikacja błędu nadal jest obecna jako tekst w DOM. To weryfikuje, że komunikacja błędu nie opiera się wyłącznie na kolorze lub ikonografii.
  7. Kontrola dynamicznego wstrzykiwania: W przypadku aplikacji jednostronicowych lub formularzy z walidacją w czasie rzeczywistym użyj narzędzi deweloperskich przeglądarki, aby zbadać DOM po wywołaniu błędu. Potwierdź, że element komunikatu o błędzie istnieje w DOM, zawiera niepusty tekst i jest referencjonowany przez odpowiednie pole wejściowe za pomocą aria-describedby lub aria-errormessage.

Jak Naprawić

Scenariusz 1: Błąd sygnalizowany wyłącznie kolorem — Nieprawidłowe

<!-- Fail: red border added via class, no error text associated -->
<label for='email'>Email Address</label>
<input type='email' id='email' name='email' class='input-error'>
<!-- CSS sets border: 2px solid red on .input-error -->
<!-- No error message text is rendered in the DOM -->

Scenariusz 1: Błąd sygnalizowany wyłącznie kolorem — Prawidłowe

<!-- Pass: error text is present, visible, and linked to the input -->
<label for='email'>Email Address</label>
<input
  type='email'
  id='email'
  name='email'
  class='input-error'
  aria-describedby='email-error'
  aria-invalid='true'
>
<!-- aria-invalid signals the error state to assistive technologies -->
<!-- aria-describedby links the input to its error message by ID -->
<p id='email-error' role='alert'>
  Please enter a valid email address, for example: [email protected]
</p>

Scenariusz 2: Ogólny podsumowujący komunikat o błędzie bez wskazania pól — Nieprawidłowe

<!-- Fail: a summary alert exists but does not identify which fields failed -->
<div role='alert'>
  <p>There are errors in the form. Please correct them and try again.</p>
</div>
<label for='phone'>Phone Number</label>
<input type='tel' id='phone' name='phone' class='is-invalid'>
<!-- No per-field error message; user cannot determine which field failed -->

Scenariusz 2: Ogólny podsumowujący komunikat o błędzie bez wskazania pól — Prawidłowe

<!-- Pass: summary lists specific fields in error, and each field has inline error text -->
<div role='alert' aria-labelledby='error-heading'>
  <h2 id='error-heading'>2 errors found. Please fix the following:</h2>
  <ul>
    <li><a href='#phone'>Phone Number: must contain only digits and be 10 characters long</a></li>
    <li><a href='#dob'>Date of Birth: required field — please enter your date of birth</a></li>
  </ul>
</div>
<label for='phone'>Phone Number</label>
<input
  type='tel'
  id='phone'
  name='phone'
  aria-describedby='phone-error'
  aria-invalid='true'
>
<!-- Inline error linked via aria-describedby -->
<p id='phone-error'>Phone Number must contain only digits and be 10 characters long.</p>

Scenariusz 3: Uszkodane odwołanie aria-describedby — Nieprawidłowe

<!-- Fail: aria-describedby references an ID that does not exist in the DOM -->
<label for='username'>Username</label>
<input
  type='text'
  id='username'
  name='username'
  aria-describedby='username-msg'
  aria-invalid='true'
>
<!-- The element with id='username-msg' was never rendered or was removed -->
<!-- Screen readers find no target and announce nothing for the description -->

Scenariusz 3: Uszkodane odwołanie aria-describedby — Prawidłowe

<!-- Pass: the referenced element exists in the DOM with matching ID -->
<label for='username'>Username</label>
<input
  type='text'
  id='username'
  name='username'
  aria-describedby='username-msg'
  aria-invalid='true'
>
<!-- Element with matching id is present and contains descriptive text -->
<span id='username-msg'>
  Username must be between 4 and 20 characters and contain only letters and numbers.
</span>

Scenariusz 4: Błąd walidacji w czasie rzeczywistym wstrzykiwany dynamicznie — Nieprawidłowe

<!-- Fail: error injected into DOM but not associated with input; no live region -->
<label for='password'>Password</label>
<input type='password' id='password' name='password'>
<!-- After blur, JavaScript appends this element, but no aria-describedby on input -->
<div class='error-text'>Password is too short.</div>

Scenariusz 4: Błąd walidacji w czasie rzeczywistym wstrzykiwany dynamicznie — Prawidłowe

<!-- Pass: error container pre-exists in DOM (empty), input references it; aria-live announces changes -->
<label for='password'>Password</label>
<input
  type='password'
  id='password'
  name='password'
  aria-describedby='password-error'
  aria-invalid='false'
>
<!-- Empty span present at page load; JavaScript populates text and sets aria-invalid='true' on error -->
<span id='password-error' aria-live='polite'></span>
<!-- JavaScript on blur: -->
<!-- document.getElementById('password-error').textContent = 'Password must be at least 8 characters.'; -->
<!-- document.getElementById('password').setAttribute('aria-invalid', 'true'); -->

Najczęstsze Błędy

  • Używanie wyłącznie zmian klas CSS (np. dodanie border-color: red) do sygnalizowania błędów bez odpowiadającego im tekstu w DOM. Sam kolor nie jest postrzegalny dla osób niewidomych lub z daltonizmem i narusza zarówno 3.3.1, jak i 1.4.1.
  • Zapisywanie aria-describedby na polu wejściowym, ale wskazywanie identyfikatora, który jest warunkowo renderowany lub usuwany z DOM przy resetowaniu walidacji. Uszkodane odwołanie oznacza, że czytnik ekranu nie znajduje powiązanej treści, a błąd jest w praktyce niewidoczny dla użytkowników technologii asystujących.
  • Używanie tekstu placeholder jako jedynego komunikatu o błędzie. Tekst placeholder znika, gdy użytkownik zaczyna pisać, często ma niski kontrast i nie jest niezawodnie odczytywany przez wszystkie czytniki ekranu jako część opisu pola w stanie błędu.
  • Dynamiczne wstrzykiwanie komunikatów o błędach do DOM bez zapewnienia ich powiązania z nadrzędnym polem za pomocą aria-describedby. Wizualnie sąsiadujący komunikat o błędzie nie jest automatycznie powiązany z polem wejściowym — powiązanie programowe musi być jawne.
  • Wyświetlanie podsumowania błędów na poziomie strony bez powiązania każdego elementu podsumowania z konkretnym polem z błędem. Użytkownicy czytników ekranu lub nawigacji klawiaturą muszą mieć możliwość przejścia bezpośrednio z opisu błędu do pola wymagającego poprawy.
  • Ustawianie aria-invalid='true' na polu bez dostarczenia tekstowego komunikatu o błędzie. Atrybut aria-invalid sygnalizuje, że pole jest w stanie błędu, ale nie opisuje błędu — musi być połączony z opisowym komunikatem.
  • Podawanie komunikatów o błędach, które są zbyt ogólne, takich jak „Invalid input” lub „Error in field”. Takie opisy nie wyjaśniają, co jest nie tak ani jak to naprawić, nie spełniając wymogu opisowości 3.3.1 i niepotrzebnie utrudniając poprawę błędów wszystkim użytkownikom.
  • Usuwanie regionów aria-live lub role='alert' z kontenerów błędów podczas resetowania formularza, co powoduje zniknięcie kontenerów, zanim czytniki ekranu zakończą odczytywanie ich treści. Komunikaty o błędach mogą zostać ucięte, pozostawiając użytkownika nieświadomym wyniku walidacji.
  • Poleganie na natywnych dymkach walidacyjnych przeglądarki (domyślne podpowiedzi narzędziowe) bez dostosowania. Natywne interfejsy walidacji przeglądarek są niespójne między przeglądarkami i kombinacjami technologii asystujących i często nie spełniają wymogów WCAG dotyczących identyfikacji i opisu w złożonych scenariuszach formularzy.
  • Umieszczanie komunikatów o błędach wizualnie daleko od powiązanych pól — na przykład wyłącznie w polu alertu w nagłówku — bez zapewnienia komunikatów inline w pobliżu każdego pola. Użytkownicy słabowidzący, którzy powiększają ekran, mogą nie widzieć alertu w nagłówku, gdy fokus znajduje się w obszarze pola, a użytkownicy klawiatury muszą pokonać znaczną odległość, aby odczytać błąd.

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 dla szerokiego zakresu podmiotów działających w Turcji. Okrężnica przyjmuje WCAG 2.2 jako standard techniczny, czyniąc wszystkie kryteria sukcesu na poziomie A — w tym WCAG 3.3.1 Identyfikacja błędu — prawnie obowiązkowymi dla objętych organizacji.

Harmonogram zgodności określony w okrężnicy to jeden rok dla instytucji publicznych i dwa lata dla podmiotów sektora prywatnego od daty publikacji. Oznacza to, że instytucje publiczne muszą osiągnąć zgodność z WCAG 2.2 na poziomie A do czerwca 2026 r., a objęte podmioty sektora prywatnego do czerwca 2027 r.

Podmioty objęte okrężnicą obejmują szeroki przekrój tureckich usług cyfrowych. Instytucje publiczne — w tym wszystkie ministerstwa rządu centralnego, gminy, uniwersytety państwowe i agencje publiczne — są zobowiązane zapewnić dostępność swoich usług cyfrowych. W sektorze prywatnym okrężnica obejmuje 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 WCAG 3.3.1 ma bezpośrednie znaczenie wszędzie tam, gdzie używane są formularze online — co w praktyce oznacza niemal każdy cyfrowy punkt kontaktu. Formularze realizacji zamówienia w e-commerce, procesy otwierania rachunków bankowych, portale rejestracji pacjentów w szpitalach, formularze wniosków o świadczenia rządowe, systemy rezerwacji biletów lotniczych i autobusowych oraz strony rekrutacji do szkół — wszystkie opierają się na walidacji formularzy. Jeśli którykolwiek z tych systemów automatycznie wykrywa błąd danych wejściowych i nie identyfikuje pola ani nie opisuje błędu w tekście, jest to bezpośrednie naruszenie wymogów okrężnicy.

Brak zgodności z okrężnicą może narazić objęte podmioty na kontrolę regulacyjną, ryzyko reputacyjne i potencjalne sankcje w miarę dojrzewania tureckich mechanizmów egzekwowania dostępności cyfrowej. Poza zgodnością prawną, przestrzeganie 3.3.1 świadczy o zaangażowaniu w inkluzywne świadczenie usług — zapewniając, że wszyscy obywatele, w tym około 8,5 miliona osób z niepełnosprawnościami w Turcji (według danych TÜİK), mogą bez barier korzystać z kluczowych usług online. Organizacje działające w ramach frameworka SDK Accsible powinny priorytetowo traktować zarówno automatyczną zgodność strukturalną, jak i dokładne testy ręczne, aby upewnić się, że ich obsługa błędów w pełni spełnia to fundamentalne kryterium.