Kryteria sukcesu WCAG · Level AAA

WCAG 2.3.3: Animacja wynikająca z interakcji

- Przeanalizuję znaczenie i ton oryginalnego tekstu. - Zachowam strukturę zdań oraz wszystkie podziały na akapity i wiersze. - Przetłumaczę terminologię techniczną zgodnie z przyjętymi standardami w języku polskim. - Utrzymam liczby, symbole i nazwy własne w oryginalnej formie. - Zweryfikuję, czy tłumaczenie wiernie oddaje sens i styl oryginału. WCAG 2.3.3 wymaga, aby animacje ruchu wywoływane przez interakcję użytkownika mogły zostać wyłączone, chyba że animacja jest niezbędna dla funkcjonalności lub przekazywanej informacji. Ma to znaczenie, ponieważ ruch może wywoływać zaburzenia przedsionkowe, powodując zawroty głowy, nudności i dezorientację u znaczącej części populacji.

Co Oznacza Ta Zasada

WCAG 2.3.3 — Animacja wynikająca z interakcji to kryterium poziomu AAA w ramach zasady Operable (Możliwość obsługi). Wymaga ono, aby każdą animację ruchu wywoływaną przez interakcję użytkownik mógł wyłączyć, chyba że animacja ta jest niezbędna dla funkcjonalności lub informacji, które są przekazywane. Kryterium dotyczy animacji inicjowanych działaniami użytkownika, takimi jak klikanie, przewijanie, najechanie kursorem, ustawienie fokusu lub jakakolwiek inna forma interakcji — nie dotyczy natomiast animacji odtwarzanych automatycznie przy ładowaniu strony (które mogą podlegać innym kryteriom, takim jak 2.2.2 Pauza, Zatrzymanie, Ukrycie).

Kluczowym pojęciem jest tutaj animacja ruchu. Obejmuje ona efekty przewijania paralaksy, animacje przejść między stronami, przesuwanie lub powiększanie elementów, obracające się wskaźniki oraz każdy inny ruch, który występuje jako bezpośrednia konsekwencja działania użytkownika. Nie obejmuje prostych zanikań (opacity) czy zmian koloru, ponieważ nie wiążą się one z ruchem w przestrzeni, który może wywoływać reakcje przedsionkowe. Różnica polega na ruchu w przestrzeni (który może powodować szkodę) oraz zmianach wyglądu bez przemieszczenia przestrzennego (które zazwyczaj nie powodują szkody).

Spełnienie kryterium wymaga, aby użytkownicy mieli niezawodny mechanizm wyłączenia takich animacji bez utraty dostępu do tej samej treści lub funkcjonalności. Najpowszechniej akceptowaną techniką jest respektowanie systemowego zapytania medialnego prefers-reduced-motion, które odzwierciedla preferencję systemu użytkownika dotyczącą ograniczenia ruchu. Alternatywnie, przełącznik na poziomie serwisu, umieszczony w widocznym miejscu interfejsu — na przykład w panelu ustawień lub widżecie dostępności — może spełnić kryterium, pod warunkiem że jego ustawienie utrzymuje się między sesjami i jest łatwe do znalezienia.

Wyjątek dotyczący elementów niezbędnych jest wąski: animacja jest niezbędna tylko wtedy, gdy jej usunięcie zasadniczo zmieniłoby informację lub funkcjonalność i nie istnieje równoważna, nieanimowana alternatywa. Obracający się wskaźnik ładowania, który jest jedyną wizualną wskazówką, że treść jest pobierana, może się kwalifikować; dekoracyjny obraz tła z efektem paralaksy poruszający się podczas przewijania przez użytkownika nie kwalifikuje się, nawet jeśli jest estetycznie centralnym elementem projektu.

Kryterium nie wymaga całkowitego usunięcia animacji — jedynie istnienia mechanizmu ich wyłączenia. Po włączeniu tego mechanizmu treść musi pozostać w pełni dostępna, co oznacza, że nieanimowana alternatywa musi przekazywać tę samą informację lub realizować tę samą funkcję.

Dlaczego To Ma Znaczenie

Zaburzenia przedsionkowe — schorzenia dotyczące ucha wewnętrznego i mózgu, które kontrolują równowagę i ruchy oczu — dotykają znaczną część światowej populacji. Według Vestibular Disorders Association około 35% dorosłych w wieku 40 lat i więcej w Stanach Zjednoczonych doświadczyło jakiejś formy dysfunkcji przedsionkowej. Na całym świecie schorzenia takie jak łagodne położeniowe zawroty głowy (BPPV), choroba Ménière’a i migreny przedsionkowe dotykają dziesiątek milionów osób. Dla tych osób ruch na ekranie może wywołać natychmiastowe objawy fizyczne, w tym zawroty głowy, vertigo, nudności, bóle głowy, a w ciężkich przypadkach czasową niezdolność do funkcjonowania.

Rozważ użytkownika z migreną przedsionkową, który odwiedza stronę rezerwacji podróży. Serwis wykorzystuje pełnoekranowy efekt przewijania paralaksy, w którym obraz w sekcji hero porusza się z inną prędkością niż treść strony podczas przewijania. W ciągu kilku sekund od rozpoczęcia przewijania użytkownik doświadcza silnych zawrotów głowy i nudności. Nie jest w stanie dokończyć rezerwacji i musi całkowicie porzucić stronę — nie z powodu bariery poznawczej czy niepełnosprawności ruchowej, lecz z powodu fizycznej reakcji na ruch na ekranie. To jest realna szkoda, której zapobieganiu służy WCAG 2.3.3.

Poza zaburzeniami przedsionkowymi animacje ruchu mogą negatywnie wpływać na użytkowników z zaburzeniami koncentracji uwagi, dla których utrzymujący się lub wywoływany ruchem ruch jest rozpraszający i trudny do zignorowania, a także na użytkowników z zaburzeniami lękowymi, dla których nieoczekiwany ruch może powodować stres. Osoby wracające do zdrowia po wstrząśnieniach mózgu lub urazach mózgu są również bardzo wrażliwe na ruch wizualny. Nawet użytkownicy bez zdiagnozowanych schorzeń mogą odczuwać zmęczenie przy intensywnym wykorzystaniu animacji podczas dłuższych sesji.

Z perspektywy użyteczności i biznesu respektowanie preferencji ograniczenia ruchu koreluje z wyższymi wskaźnikami ukończenia zadań i dłuższym czasem sesji wśród wrażliwych użytkowników. Szacunek dla preferencji na poziomie systemu sygnalizuje również, że produkt jest dobrze zaprojektowany i uwzględnia potrzeby użytkowników, co buduje zaufanie. W e-commerce, gdzie porzucanie koszyka z powodu złego doświadczenia bezpośrednio wpływa na przychody, usuwanie zbędnych barier związanych z animacją stanowi konkretną korzyść komercyjną.

Powiązane Reguły Axe-core

WCAG 2.3.3 wymaga ręcznego testowania. Żadna zautomatyzowana reguła axe-core nie mapuje się bezpośrednio na to kryterium i jest to zamierzone, a nie przeoczenie. Powody, dla których narzędzia automatyczne nie mogą wiarygodnie wykrywać naruszeń, są istotne:

  • Dlaczego automatyzacja nie może tego wychwycić: Wykrycie animacji ruchu wymaga zrozumienia wizualnego renderowania strony w czasie w odpowiedzi na interakcję użytkownika. Zautomatyzowane skanery dostępności analizują statyczne lub częściowo renderowane zrzuty DOM; nie symulują interakcji użytkownika, takich jak przewijanie czy klikanie, a następnie obserwowania, czy przejścia CSS lub animacje sterowane JavaScriptem powodują ruch przestrzenny. Nawet jeśli skaner mógłby wykryć obecność właściwości animacji lub przejść CSS, nie jest w stanie określić, czy animacja obejmuje przemieszczenie przestrzenne (które może wywołać reakcje przedsionkowe), czy jedynie proste zanikanie (opacity), które ich nie wywołuje. Ponadto skaner nie może ustalić, czy zapytanie medialne prefers-reduced-motion jest poprawnie podłączone, aby tłumić animację, czy istnieje przełącznik na poziomie serwisu ani czy animacja jest rzeczywiście niezbędna. Wszystkie te oceny wymagają testera-ludzi, który może obserwować wyrenderowane doświadczenie, wchodzić w interakcję ze stroną i oceniać wynik.
  • Na czym powinna się skupić ręczna inspekcja: Testerzy muszą zidentyfikować każdą właściwość CSS, która tworzy ruch przestrzenny — w tym transform: translateX/Y/Z, transform: scale, transform: rotate, przejścia top/left/margin, klatki kluczowe animation przemieszczające elementy w przestrzeni — i zweryfikować, że każda z nich jest kontrolowana przez zapytanie medialne prefers-reduced-motion: reduce lub przełącznik sterowany przez użytkownika. Animacje sterowane JavaScriptem z użyciem bibliotek takich jak GSAP, Framer Motion czy własnych pętli requestAnimationFrame muszą być przeglądane z równą starannością.

Jak Testować

  1. Włącz Ograniczenie Ruchu na poziomie systemu operacyjnego: W macOS przejdź do Ustawienia systemowe > Dostępność > Ekran i włącz „Ogranicz ruch” (Reduce Motion). W Windows 11 przejdź do Ustawienia > Ułatwienia dostępu > Efekty wizualne i wyłącz „Efekty animacji” (Animation effects). W iOS przejdź do Ustawienia > Dostępność > Ruch i włącz „Ogranicz ruch” (Reduce Motion). W Androidzie przejdź do Ustawienia > Dostępność > Usuń animacje (Remove Animations). Ustawia to zapytanie medialne prefers-reduced-motion: reduce jako aktywne.
  2. Uruchom automatyczny skan jako punkt odniesienia: Otwórz axe DevTools lub Lighthouse w Chrome DevTools dla testowanej strony. Choć żadne z narzędzi nie zgłosi bezpośrednio naruszenia WCAG 2.3.3, skan może ujawnić powiązane problemy i potwierdza, że środowisko testowe działa. Zanotuj wszelkie znaleziska związane z animacją dla kontekstu.
  3. Wchodź w interakcję ze stroną przy aktywnym Ograniczeniu Ruchu w systemie: Przewijaj stronę powoli, klikaj elementy interaktywne, takie jak przyciski, przełączniki nawigacji, rozwijane listy, karuzele i modale. Najeżdżaj kursorem na elementy. Przechodź po stronie za pomocą klawiatury (Tab). Obserwuj, czy nadal odtwarzane są jakiekolwiek animacje ruchu przestrzennego. Jeśli animacje są tłumione, jest to wynik pozytywny dla ścieżki preferencji systemowych.
  4. Wyłącz Ograniczenie Ruchu w systemie i przetestuj ponownie: Przy wyłączonym Ograniczeniu Ruchu powtórz wszystkie interakcje. Zidentyfikuj każdą animację ruchu wywoływaną interakcją użytkownika. Udokumentuj każdą z nich, opisując działanie wyzwalające i zaobserwowaną animację.
  5. Sprawdź, czy istnieje przełącznik animacji na poziomie serwisu: Jeśli Ograniczenie Ruchu systemu nie jest respektowane, poszukaj kontrolki na poziomie serwisu — zwykle w widżecie dostępności, menu ustawień lub stopce. Aktywuj ją i powtórz wszystkie testy interakcji, aby potwierdzić, że ruch jest tłumiony.
  6. Sprawdź w CSS i JavaScript implementację prefers-reduced-motion: Otwórz DevTools, przejdź do panelu Sources lub Elements i wyszukaj prefers-reduced-motion w plikach arkuszy stylów. Zweryfikuj, że wszystkie zidentyfikowane animacje ruchu są kontrolowane przez to zapytanie. W Chrome DevTools możesz emulować zapytanie medialne: otwórz kartę Rendering (More Tools > Rendering) i ustaw „Emulate CSS media feature prefers-reduced-motion” na „reduce”. Potwierdź, że animacje są tłumione bez konieczności ponownego uruchamiania przeglądarki.
  7. Oceń wyjątki niezbędności: Dla każdej pozostałej animacji przy aktywnym ograniczeniu ruchu oceń, czy jest ona rzeczywiście niezbędna — czy jej usunięcie eliminuje informację lub funkcjonalność, która nie ma nieanimowanego odpowiednika? Udokumentuj swoje uzasadnienie dla każdej decyzji.
  8. Weryfikacja z czytnikami ekranu (NVDA + Firefox, JAWS + Chrome, VoiceOver + Safari): Użytkownicy czytników ekranu nie są odporni na efekty przedsionkowe, jeśli mają częściowy wzrok. Nawiguj po stronie wyłącznie klawiaturą przy aktywnym czytniku ekranu i włączonym Ograniczeniu Ruchu w systemie. Potwierdź, że żadne animacje nie są wywoływane zdarzeniami fokusu lub interakcjami sterowanymi klawiaturą, które nie uwzględniają ograniczenia ruchu.

Jak Naprawić

Efekt przewijania paralaksy — Niepoprawne

<!-- Background moves at a different rate than content on scroll -->
<style>
  .hero {
    background-image: url('hero.jpg');
    background-attachment: fixed; /* Creates parallax on scroll */
    height: 100vh;
  }
</style>
<div class='hero'></div>

Efekt przewijania paralaksy — Poprawne

<!-- Parallax is disabled when the user prefers reduced motion -->
<style>
  .hero {
    background-image: url('hero.jpg');
    background-attachment: fixed; /* Parallax by default */
    height: 100vh;
  }

  @media (prefers-reduced-motion: reduce) {
    .hero {
      background-attachment: scroll; /* Static background; no spatial movement */
    }
  }
</style>
<div class='hero'></div>

Przejście CSS na elemencie interaktywnym — Niepoprawne

<!-- Button slides and scales on click with no reduced-motion accommodation -->
<style>
  .btn {
    transition: transform 0.4s ease;
  }
  .btn:active {
    transform: scale(0.9) translateY(4px);
  }
</style>
<button class='btn'>Submit</button>

Przejście CSS na elemencie interaktywnym — Poprawne

<!-- Spatial transform is suppressed; a simple opacity shift conveys state without motion -->
<style>
  .btn {
    transition: transform 0.4s ease, opacity 0.2s ease;
  }
  .btn:active {
    transform: scale(0.9) translateY(4px);
  }

  @media (prefers-reduced-motion: reduce) {
    .btn {
      transition: opacity 0.2s ease; /* Only non-spatial change retained */
    }
    .btn:active {
      transform: none; /* No movement */
      opacity: 0.75;   /* State still communicated visually */
    }
  }
</style>
<button class='btn'>Submit</button>

Biblioteka animacji JavaScript (GSAP) — Niepoprawne

<!-- GSAP tween fires on button click regardless of user motion preference -->
<script>
  document.querySelector('#open-modal').addEventListener('click', () => {
    gsap.fromTo('#modal', { y: 80, opacity: 0 }, { y: 0, opacity: 1, duration: 0.5 });
  });
</script>

Biblioteka animacji JavaScript (GSAP) — Poprawne

<!-- Check matchMedia before triggering spatial animation; fall back to instant display -->
<script>
  const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;

  document.querySelector('#open-modal').addEventListener('click', () => {
    if (prefersReducedMotion) {
      /* Skip spatial movement; just make the modal visible immediately */
      gsap.set('#modal', { opacity: 1, y: 0 });
    } else {
      gsap.fromTo('#modal', { y: 80, opacity: 0 }, { y: 0, opacity: 1, duration: 0.5 });
    }
  });
</script>

Przełącznik animacji na poziomie serwisu (widżet dostępności) — Poprawny wzorzec

<!-- Persist user preference in localStorage and apply a class to <html> -->
<button id='toggle-motion' aria-pressed='false'>Reduce Motion</button>

<style>
  /* Default: animations active */
  .card { transition: transform 0.3s ease; }
  .card:hover { transform: translateY(-8px); }

  /* When user opts out via widget */
  html.reduce-motion .card {
    transition: none;
  }
  html.reduce-motion .card:hover {
    transform: none;
  }
</style>

<script>
  const btn = document.getElementById('toggle-motion');
  const stored = localStorage.getItem('reduceMotion') === 'true';

  if (stored) {
    document.documentElement.classList.add('reduce-motion');
    btn.setAttribute('aria-pressed', 'true');
  }

  btn.addEventListener('click', () => {
    const isActive = document.documentElement.classList.toggle('reduce-motion');
    btn.setAttribute('aria-pressed', String(isActive));
    localStorage.setItem('reduceMotion', String(isActive));
  });
</script>

Typowe Błędy

  • Stosowanie prefers-reduced-motion tylko do animacji CSS, ale nie do przejść CSS: Zarówno skrót animation, jak i właściwość transition mogą powodować ruch przestrzenny. Zespoły często piszą zapytanie medialne dla animacji klatkowych i zapominają, że transition: transform 0.3s przy najechaniu lub ustawieniu fokusu również wywołuje ruch, który musi być kontrolowany.
  • Używanie prefers-reduced-motion: no-preference jako warunku zapytania zamiast reduce: Poprawny wzorzec obejmuje style z ograniczonym ruchem w @media (prefers-reduced-motion: reduce), a nie odwrotnie. Obejmowanie stylów animacji w @media (prefers-reduced-motion: no-preference) może działać, ale jest bardziej podatne na błędy i często jest stosowane nieprawidłowo, pozostawiając animacje aktywne dla użytkowników, którzy nie ustawili wyraźnej preferencji.
  • Buforowanie wyniku matchMedia tylko raz i nigdy ponowne niesprawdzanie: Użytkownik może zmienić preferencję systemową podczas otwarcia strony. Należy subskrybować matchMedia(...).addEventListener('change', handler), aby animacje sterowane JavaScriptem reagowały na zmiany preferencji w czasie rzeczywistym bez konieczności przeładowania strony.
  • Traktowanie zanikań wyłącznie na opacity jako animacji ruchu, które muszą być tłumione: Kryterium dotyczy konkretnie ruchu przestrzennego. Usuwanie przejść opacity przy aktywnym ograniczeniu ruchu jest zbyt agresywne i pogarsza użyteczność. Zanikania, które nie przemieszczają elementów w przestrzeni, są zazwyczaj akceptowalne do pozostawienia.
  • Umieszczanie przełącznika animacji głęboko w niedostępnym menu ustawień: Jeśli kontrolka na poziomie serwisu jest używana zamiast (lub oprócz) zapytania medialnego systemu, musi być łatwa do znalezienia — najlepiej w stałym nagłówku serwisu, stopce lub dostępnym widżecie nakładki, a nie ukryta trzy poziomy w głąb strony ustawień konta użytkownika wymagającej logowania.
  • Zakładanie, że wszystkie biblioteki animacji automatycznie respektują prefers-reduced-motion: Większość bibliotek animacji JavaScript, w tym GSAP, Anime.js i własne implementacje requestAnimationFrame, nie respektuje automatycznie zapytania medialnego. Każda animacja programistyczna musi być indywidualnie zabezpieczona sprawdzeniem matchMedia w warstwie JavaScript.
  • Deklarowanie animacji jako niezbędnej bez odpowiedniego uzasadnienia: Zespoły czasem oznaczają złożone animacje dekoracyjne jako niezbędne, aby uniknąć prac naprawczych. Wyjątek niezbędności jest wąski; animacja jest niezbędna tylko wtedy, gdy informacji, którą przekazuje, nie można wyrazić w żaden statyczny lub nieanimowany sposób. Wskaźniki ładowania, dekoracyjna paralaksa i animacje wejścia strony prawie nigdy nie kwalifikują się jako niezbędne.
  • Nietestowanie interakcji innych niż kliknięcie — zwłaszcza przewijania i najechania: Efekty przewijania paralaksy i transformacje wywoływane najechaniem kursorem należą do najczęstszych przyczyn problemów przedsionkowych, a mimo to testy często ograniczają się do interakcji kliknięcia. Kompleksowe testowanie musi obejmować wszystkie formy interakcji, w tym przewijanie, najechanie, fokus, przeciąganie i nawigację klawiaturą.
  • Nieutrwalanie preferencji przełącznika na poziomie serwisu między sesjami: Jeśli użytkownik ustawi przełącznik serwisu na ograniczenie ruchu, a następnie przejdzie na inną stronę lub wróci do serwisu następnego dnia i ustawienie zostanie zresetowane, udogodnienie w praktyce zawiodło. Preferencje muszą być przechowywane w localStorage lub profilu użytkownika i ponownie stosowane przy każdym ładowaniu strony.
  • Zapominanie o osadzonych treściach i widżetach stron trzecich: Osadzone kanały społecznościowe, widżety czatu, osadzenia map i skrypty reklamowe mogą wprowadzać własne animacje ruchu całkowicie poza kontrolą CSS serwisu hostującego. Treści stron trzecich muszą być audytowane, a dostawcy muszą zostać zaangażowani w zapewnienie wsparcia ograniczenia ruchu lub osadzenia muszą być opakowane w kontenery, które tłumią ruch za pomocą strategii zawierania CSS, tam gdzie jest to możliwe.

Związek z Przepisami Dostępności w Turcji

Turecka Okrężnica Prezydencka 2025/10, opublikowana w Dzienniku Urzędowym (Resmî Gazete) nr 32933 w dniu 21 czerwca 2025 r., ustanawia wiążące obowiązki w zakresie dostępności cyfrowej dla określonego zestawu typów podmiotów działających w Turcji. Podmioty objęte regulacją obejmują instytucje i agencje publiczne, platformy e-commerce, banki i dostawców usług finansowych, szpitale i prywatne placówki opieki zdrowotnej, operatorów telekomunikacyjnych z 200 000 lub większą liczbą abonentów, licencjonowane biura podróży, prywatne firmy transportowe oraz szkoły prywatne upoważnione przez Ministerstwo Edukacji Narodowej (MoNE).

Okrężnica nakazuje zgodność z WCAG 2.1 na poziomie AA jako standard bazowy dla usług cyfrowych wytworzonych lub istotnie zaktualizowanych po dacie wejścia w życie. WCAG 2.3.3 — Animacja wynikająca z interakcji jest kryterium poziomu AAA, a zatem nie jest wymogiem obowiązkowym na mocy Okrężnicy Prezydenckiej 2025/10. Podmioty objęte regulacją nie są prawnie zobowiązane do wdrożenia tego kryterium, aby osiągnąć status zgodności z prawem tureckim.

Jednak osiągnięcie zgodności na poziomie AAA w zakresie kryteriów takich jak 2.3.3 niesie ze sobą istotną wartość praktyczną i reputacyjną dla tureckich organizacji. Nadwrażliwość przedsionkowa i na ruch to niepełnosprawności niewidoczne, które są często pomijane w audytach dostępności skupionych wąsko na kompatybilności z czytnikami ekranu. Dla sektorów takich jak opieka zdrowotna (szpitale i prywatne platformy zdrowotne), gdzie użytkownikami mogą być pacjenci z chorobami neurologicznymi zwiększającymi wrażliwość na ruch, oraz dla e-commerce i biur podróży, gdzie powszechne są wzorce interfejsu z intensywnym przewijaniem i animacjami, wdrożenie 2.3.3 pokazuje dojrzałe, zorientowane na użytkownika podejście do dostępności.

Organizacje dążące do dobrowolnej zgodności z poziomem AAA — takie jak te, które poszukują przewagi w przetargach publicznych, wejścia na rynki międzynarodowe lub certyfikacji branżowej — powinny traktować 2.3.3 jako kryterium priorytetowe, biorąc pod uwagę stosunkowo niski koszt naprawczy (dobrze zaprojektowana strategia zapytań medialnych prefers-reduced-motion może być zastosowana systematycznie w całym systemie projektowym) oraz bezpośredną szkodę fizyczną, jaką może powodować brak tego kryterium. Uwzględnienie kontrolki animacji w widżecie nakładki dostępności, takim jak Accsible, pozwala tureckim organizacjom oferować to udogodnienie bez konieczności szukania przez użytkowników ustawień systemu operacyjnego — czyniąc ścieżkę do ograniczenia ruchu możliwie najbardziej odkrywalną i użyteczną dla najszerszej grupy odbiorców.