WCAG 2.5.4: Sterowanie ruchem

Kryterium Sukcesu 2.5.4 Sterowanie ruchem, należące do wytycznych WCAG 2.1 na poziomie dostępności AA, ma na celu zapewnienie, że funkcjonalności obsługiwane za pomocą ruchu urządzenia (np. potrząsanie, przechylanie) lub ruchu użytkownika (np. gesty zarejestrowane przez kamerę) są również dostępne za pomocą standardowych komponentów interfejsu użytkownika. Dodatkowo, wyłączenie sterowania ruchem nie może uniemożliwić dostępu do jakiejkolwiek funkcji, chyba że ruch jest istotny dla samej funkcji lub jej podstawowego rezultatu.

To kryterium jest kluczowe dla szerokiego grona użytkowników, którzy mogą mieć trudności z wykonywaniem precyzyjnych lub celowych ruchów, co znacząco wpływa na ogólną użyteczność i inkluzywność cyfrowych doświadczeń.

Co to jest Kryterium Sukcesu 2.5.4: Sterowanie ruchem?

Kryterium Sukcesu 2.5.4 wymaga, aby wszelkie funkcje, które domyślnie wykorzystują ruch urządzenia (np. potrząsanie smartfonem w celu cofnięcia akcji, przechylanie tabletu do przewijania) lub ruch użytkownika (np. gesty głową lub ręką do nawigacji), miały alternatywną metodę obsługi dostępną poprzez elementy interfejsu użytkownika (UI). Oznacza to, że użytkownik powinien mieć możliwość wykonania tej samej akcji, klikając przycisk, używając menu rozwijanego lub innej standardowej kontrolki, zamiast polegać wyłącznie na ruchu.

Dodatkowo, użytkownik powinien mieć możliwość wyłączenia sterowania ruchem, jeśli jest to dla niego problematyczne, bez utraty dostępu do funkcjonalności, którą to sterowanie ruchem oferowało. Istnieją bardzo rzadkie wyjątki, gdzie ruch jest istotny dla funkcji (np. aplikacja do monitorowania kroków, gra, której głównym celem jest balansowanie).

Dlaczego Sterowanie ruchem ma znaczenie?

Wprowadzenie alternatywnych metod obsługi dla funkcji sterowanych ruchem jest niezwykle ważne z perspektywy dostępności i ma wpływ na wiele grup użytkowników:

Użytkownicy z niepełnosprawnościami ruchowymi

Osoby z niepełnosprawnościami motorycznymi, takimi jak drżenie, ataksja, paraliż, brak kończyn lub ograniczona zręczność, mogą mieć duże trudności z wykonywaniem precyzyjnych lub powtarzalnych ruchów wymaganych przez niektóre interfejsy. Potrząsanie, przechylanie czy obracanie urządzenia może być dla nich niemożliwe lub prowadzić do niezamierzonych akcji. Zapewnienie alternatywnych przycisków lub innych kontrolek UI pozwala im na pełne korzystanie z aplikacji i stron internetowych.

Sytuacje środowiskowe i kontekstowe

Dostępność to nie tylko kwestia niepełnosprawności, ale także kontekstu użycia. Użytkownik może znajdować się w sytuacji, która uniemożliwia lub utrudnia wykonywanie ruchów: na przykład jadąc autobusem lub pociągiem, mając zajęte ręce, używając urządzenia zamontowanego na wózku inwalidzkim, czy też w środowisku, gdzie ruchy są niestabilne. W takich przypadkach sterowanie ruchem staje się barierą, a nie udogodnieniem.

Użytkownicy z niepełnosprawnościami poznawczymi

Dla niektórych osób z niepełnosprawnościami poznawczymi, zapamiętywanie i precyzyjne wykonywanie złożonych gestów ruchowych może być trudne lub frustrujące. Standardowe kontrolki UI, takie jak przyciski czy menu, są często bardziej intuicyjne i przewidywalne, co zmniejsza obciążenie poznawcze i ryzyko błędów.

Wymagania Kryterium Sukcesu 2.5.4

Aby spełnić to kryterium, należy zwrócić uwagę na następujące aspekty:

  • Alternatywne metody obsługi: Jeśli jakakolwiek funkcja może być uruchomiona przez ruch urządzenia lub użytkownika, musi być również dostępna alternatywna metoda uruchomienia tej funkcji za pomocą komponentów interfejsu użytkownika (np. klikalny przycisk, pole wyboru, link). Ta alternatywa musi wykonywać dokładnie tę samą funkcję.

  • Brak utraty funkcjonalności: Wyłączenie mechanizmu sterowania ruchem (jeśli taka opcja jest dostępna) nie może skutkować utratą dostępu do jakiejkolwiek funkcjonalności. Użytkownik, który wyłączy sterowanie ruchem, nadal musi mieć pełną możliwość korzystania z aplikacji lub strony.

  • Wyjątki: Istnieją bardzo ograniczone sytuacje, w których ruch może być uznany za istotny i nie wymaga alternatywnej metody obsługi. Są to przypadki, gdy:

    • Ruch jest integralną częścią samej funkcji (np. w grze typu symulator lotu, gdzie przechylanie urządzenia steruje samolotem, lub w aplikacji do mierzenia kroków, gdzie ruch jest podstawą działania).
    • Ruch jest istotny dla podstawowego rezultatu funkcji (np. aplikacja do tworzenia efektów artystycznych, gdzie potrząśnięcie generuje unikalny efekt, którego nie da się uzyskać w inny sposób; ten wyjątek jest rzadko spełniany w praktyce).

    W większości przypadków ruch jest jedynie mechanizmem wyzwalającym akcję, a nie jej istotą, dlatego wymaga alternatywy.

Praktyczne wytyczne dotyczące zgodności

Aby zapewnić zgodność z SC 2.5.4, należy wdrożyć następujące praktyki:

  • Zawsze zapewniaj alternatywne interfejsy: Dla każdej funkcji aktywowanej ruchem, zaprojektuj i zaimplementuj równoważną kontrolkę UI. Upewnij się, że alternatywna kontrolka jest łatwa do znalezienia i zrozumienia.

  • Umożliwiaj wyłączenie sterowania ruchem: Jeśli używasz sterowania ruchem, rozważ dodanie opcji w ustawieniach aplikacji lub strony, która pozwoli użytkownikom wyłączyć tę funkcję. Wyłączenie nie może wpływać na dostępność alternatywnych metod.

  • Testuj z różnymi metodami wprowadzania: Upewnij się, że alternatywne kontrolki UI są dostępne i funkcjonalne dla użytkowników korzystających z klawiatury, myszy, ekranu dotykowego oraz technologii wspomagających (np. czytników ekranu).

  • Ostrożnie oceniaj „istotność” ruchu: Bądź bardzo ostrożny przy klasyfikowaniu ruchu jako „istotnego”. Zawsze zadawaj sobie pytanie, czy sama czynność lub jej wynik nie mogą być osiągnięte w żaden inny sposób. Jeśli ruch jest tylko wygodnym skrótem lub alternatywą, nie jest „istotny”.

Przykłady implementacji

Przykład 1: Cofanie akcji (potrząśnij, aby cofnąć)

Poprawna implementacja

W tym przykładzie, oprócz gestu potrząśnięcia, dostępny jest również przycisk „Cofnij”, który wykonuje tę samą akcję. Użytkownik może wybrać preferowaną metodę.

<button id="undoButton">Cofnij</button>

<script>
  // Funkcja, która wykonuje akcję cofania
  function undoAction() {
    alert('Akcja została cofnięta!');
    // Tutaj właściwa logika cofania akcji
  }

  // 1. Alternatywa: Aktywacja za pomocą przycisku UI
  document.getElementById('undoButton').addEventListener('click', undoAction);

  // 2. Funkcja sterowana ruchem (np. potrząśnięcie urządzeniem)
  // W prawdziwej aplikacji detekcja potrząśnięcia byłaby bardziej zaawansowana
  let lastShakeTime = 0;
  const shakeThreshold = 20; // Przykładowy próg przyspieszenia
  const minTimeBetweenShakes = 500; // Minimalny czas między potrząśnięciami (ms)

  window.addEventListener('devicemotion', function(event) {
    const acceleration = event.accelerationIncludingGravity;
    const now = Date.now();

    // Prosta detekcja potrząśnięcia na podstawie sumy wartości bezwzględnych przyspieszeń
    if (Math.abs(acceleration.x) > shakeThreshold || 
        Math.abs(acceleration.y) > shakeThreshold || 
        Math.abs(acceleration.z) > shakeThreshold) {

      if (now - lastShakeTime > minTimeBetweenShakes) {
        console.log('Wykryto potrząśnięcie!');
        // Sprawdź, czy sterowanie ruchem jest włączone w ustawieniach użytkownika
        // if (userSettings.motionShakeToUndoEnabled) {
              undoAction();
        // }
        lastShakeTime = now;
      }
    }
  });

  // Założenie: Ustawienie użytkownika do włączania/wyłączania sterowania ruchem
  // const userSettings = { motionShakeToUndoEnabled: true };
</script>

Niepoprawna implementacja

W tym przykładzie użytkownik może cofnąć akcję wyłącznie poprzez potrząśnięcie urządzeniem, co jest niedostępne dla wielu osób.

<p>Potrząśnij urządzeniem, aby cofnąć ostatnią akcję.</p>

<script>
  // Tylko obsługa ruchu, brak alternatywnego przycisku UI
  let lastShakeTime = 0;
  const shakeThreshold = 20;
  const minTimeBetweenShakes = 500;

  window.addEventListener('devicemotion', function(event) {
    const acceleration = event.accelerationIncludingGravity;
    const now = Date.now();

    if (Math.abs(acceleration.x) > shakeThreshold || 
        Math.abs(acceleration.y) > shakeThreshold || 
        Math.abs(acceleration.z) > shakeThreshold) {

      if (now - lastShakeTime > minTimeBetweenShakes) {
        alert('Akcja została cofnięta! (tylko potrząśnięcie)');
        // Tutaj właściwa logika cofania akcji
        lastShakeTime = now;
      }
    }
  });
</script>

Przykład 2: Nawigacja po mapie przez przechylanie

Poprawna implementacja

Mapa umożliwia nawigację zarówno poprzez przechylanie urządzenia, jak i poprzez klikanie standardowych przycisków „Góra”, „Dół”, „Lewo”, „Prawo”.

<div class="map-container">
  <!-- Alternatywne przyciski nawigacyjne -->
  <button aria-label="Przesuń mapę w górę" onclick="moveMap('up')">&#9650;</button>
  <div style="display: flex;">
    <button aria-label="Przesuń mapę w lewo" onclick="moveMap('left')">&#9664;</button>
    <div id="map" style="width: 300px; height: 200px; border: 1px solid black; display: flex; align-items: center; justify-content: center; background-color: lightblue;">Mapa</div>
    <button aria-label="Przesuń mapę w prawo" onclick="moveMap('right')">&#9654;</button>
  </div>
  <button aria-label="Przesuń mapę w dół" onclick="moveMap('down')">&#9660;</button>
</div>

<script>
  let currentX = 0;
  let currentY = 0;
  const mapElement = document.getElementById('map');

  function moveMap(direction) {
    console.log('Przesuwam mapę:', direction);
    // Symulacja przesuwania mapy
    switch (direction) {
      case 'up': currentY -= 10; break;
      case 'down': currentY += 10; break;
      case 'left': currentX -= 10; break;
      case 'right': currentX += 10; break;
    }
    mapElement.style.backgroundPosition = `${currentX}px ${currentY}px`;
    mapElement.textContent = `Mapa (X:${currentX}, Y:${currentY})`;
  }

  // Funkcja sterowana ruchem (np. przechylanie urządzenia)
  // Założenie: użytkownik ma opcję włączenia/wyłączenia tej funkcji
  let motionNavigationEnabled = true; // Zmienna sterowana przez ustawienia użytkownika

  window.addEventListener('deviceorientation', function(event) {
    if (!motionNavigationEnabled) return;

    const tiltLR = event.gamma; // od -90 do 90 (lewo-prawo)
    const tiltFB = event.beta;  // od -180 do 180 (przód-tył)
    const tiltThreshold = 10; // Próg dla przechylenia

    // Prosta logika nawigacji mapy przez przechylanie
    if (tiltLR > tiltThreshold) {
      moveMap('right');
    } else if (tiltLR < -tiltThreshold) {
      moveMap('left');
    }

    if (tiltFB > tiltThreshold) {
      moveMap('down');
    } else if (tiltFB < -tiltThreshold) {
      moveMap('up');
    }
  });
</script>

Niepoprawna implementacja

Użytkownik może nawigować po mapie tylko poprzez przechylanie urządzenia, co stanowi poważną barierę dostępności.

<div id="map" style="width: 300px; height: 200px; border: 1px solid black; display: flex; align-items: center; justify-content: center; background-color: lightblue;">
  <p>Przechyl urządzenie, aby nawigować po mapie.</p>
</div>

<script>
  let currentX = 0;
  let currentY = 0;
  const mapElement = document.getElementById('map');
  const tiltThreshold = 10;

  // Tylko obsługa ruchu, brak alternatywnych przycisków
  window.addEventListener('deviceorientation', function(event) {
    const tiltLR = event.gamma; 
    const tiltFB = event.beta;
    
    // Logika nawigacji mapy oparta wyłącznie na przechylaniu
    if (tiltLR > tiltThreshold) {
      currentX += 10;
    } else if (tiltLR < -tiltThreshold) {
      currentX -= 10;
    }

    if (tiltFB > tiltThreshold) {
      currentY += 10;
    } else if (tiltFB < -tiltThreshold) {
      currentY -= 10;
    }
    mapElement.style.backgroundPosition = `${currentX}px ${currentY}px`;
    mapElement.textContent = `Mapa (X:${currentX}, Y:${currentY})`;
  });
</script>

Dobre praktyki i typowe pułapki

Dobre praktyki

  • Udostępnij jasne instrukcje: Jeśli używasz sterowania ruchem, poinformuj użytkownika o tej funkcji i jasno wskaż, że istnieje również alternatywna metoda obsługi.

  • Zapewnij opcje personalizacji: Umożliwienie użytkownikom włączania i wyłączania sterowania ruchem w ustawieniach zwiększa kontrolę i użyteczność.

  • Wykonuj testy użyteczności: Testuj funkcje sterowane ruchem i ich alternatywy z rzeczywistymi użytkownikami, w tym z osobami z różnymi niepełnosprawnościami i w różnych warunkach (np. w ruchu).

  • Upewnij się, że alternatywa jest równie efektywna: Alternatywna metoda obsługi powinna być równie łatwa w użyciu i zapewniać pełną funkcjonalność, co metoda sterowana ruchem.

Typowe pułapki

  • Brak alternatywnych metod: Najczęstszym błędem jest poleganie wyłącznie na sterowaniu ruchem bez zapewnienia jakiejkolwiek alternatywy UI.

  • Niewłaściwe zastosowanie wyjątku "istotności": Deweloperzy często błędnie interpretują ruch jako "istotny", nawet jeśli funkcja może być zrealizowana inaczej (np. aplikacja do robienia notatek, gdzie "potrząśnij, aby usunąć" jest interpretowane jako "istotne").

  • Brak możliwości wyłączenia: Nieoferowanie użytkownikowi możliwości wyłączenia sterowania ruchem, nawet jeśli istnieją alternatywy, może być problematyczne dla osób, które przypadkowo wywołują akcje ruchem.

  • Złożone gesty ruchu: Implementowanie skomplikowanych sekwencji ruchów, które są trudne do zapamiętania i precyzyjnego wykonania, nawet dla osób bez niepełnosprawności.

Podsumowanie

Kryterium Sukcesu 2.5.4 Sterowanie ruchem jest istotnym elementem tworzenia dostępnych i użytecznych interfejsów cyfrowych. Zapewniając alternatywne metody obsługi dla funkcji sterowanych ruchem, deweloperzy i projektanci mogą usunąć bariery dla szerokiego grona użytkowników, w tym osób z niepełnosprawnościami ruchowymi oraz tych znajdujących się w niekorzystnych warunkach środowiskowych. Przestrzeganie tego kryterium nie tylko poprawia dostępność, ale także zwiększa ogólną elastyczność i komfort użytkowania aplikacji i stron internetowych dla wszystkich.

Przegląd prywatności

Ta strona korzysta z ciasteczek, aby zapewnić Ci najlepszą możliwą obsługę. Informacje o ciasteczkach są przechowywane w przeglądarce i wykonują funkcje takie jak rozpoznawanie Cię po powrocie na naszą stronę internetową i pomaganie naszemu zespołowi w zrozumieniu, które sekcje witryny są dla Ciebie najbardziej interesujące i przydatne.