← Wszystkie wpisy

Gramatyka ruchu: kiedy animacja zasługuje na swoje klatki

Większość animacji interfejsu to dekoracja z przypiętą odznaką funkcji. Test, który stosuję, jest bezlitosny: jeśli nie da się wyjaśnić, co dana animacja mówi użytkownikowi, nie zasługuje ona na swoje klatki i trzeba ją usunąć. To, co przetrwa ten test, okazuje się bardzo skromną gramatyką: cztery pasma czasu trwania, dwie reguły easingu i garść zadań, które ruch wykonuje naprawdę lepiej niż statyczna zmiana. Cała reszta to projektant zabawiający sam siebie kosztem użytkownika, po szesnaście milisekund naraz. {.answer-block}

W skrócie

  • Ruch albo niesie informację, albo jest szumem. Zadania uprawnione: pokazanie, skąd coś przyszło lub dokąd odeszło, potwierdzenie, że akcja została zarejestrowana, kierowanie uwagą w trakcie zmiany oraz maskowanie nieuniknionego opóźnienia. Wszystko inne należy wyciąć.
  • Cztery pasma czasu trwania pokrywają cały interfejs: ~100ms na naciśnięcia i przełączniki, 150-200ms na najechania kursorem i przenikania, 250-300ms na rozwijanie i zwijanie, 300-400ms na przejścia między stronami i okna modalne.
  • Dwie reguły easingu pokrywają wejścia i wyjścia: ease-out dla wszystkiego, co wchodzi, ease-in dla wszystkiego, co wychodzi. Elementy, które przemieszczają się, pozostając na ekranie, dostają ease-in-out; linear zarezerwowany jest dla pasków postępu i czystych przenikań.
  • Test usunięcia stoi wyżej niż test gustu. Pytanie „czy to miło wygląda” utrzymuje złą animację przy życiu; pytanie „co to mówi użytkownikowi” ją zabija.
  • prefers-reduced-motion należy traktować jako wymaganie pierwszej kategorii, a nie jako refleksję po fakcie — gramatyka musi degradować się do natychmiastowych zmian stanu i nadal mieć sens.

Ruch jest zdaniem, nie nastrojem

Animacja interfejsu to twierdzenie o przyczynowości: ten panel wyszedł z tamtego przycisku; ten element odszedł na tamtą listę; ta zmiana zaszła, ponieważ ktoś zadziałał. Kiedy ruch niesie jedno z takich twierdzeń, model mentalny użytkownika aktualizuje się za darmo — bez czytania, bez wnioskowania. Kiedy nie niesie niczego, użytkownik czeka na koniec choreografii, zanim będzie mógł działać dalej, a każde takie czekanie jest niewielkim podatkiem od zaufania.

Z takiego ujęcia wynika robocza lista zadań, które ruch faktycznie ma do wykonania:

  1. Ciągłość przestrzenna — skąd to przyszło, dokąd odeszło. Rozwijająca się karta, arkusz wznoszący się ze swojego wyzwalacza, usunięty wiersz zwijający się w stronę ikony archiwum.
  2. Potwierdzenie — naciśnięcie zostało zarejestrowane. Wciśnięcie przycisku trwające 100ms, przerzut przełącznika, ptaszek w polu wyboru.
  3. Kierowanie uwagą — podczas zmiany stanu to, co jako jedyne się poruszyło, jest tym, co jako jedyne się zmieniło. Ruch należy do najsilniejszych sygnałów uwagi, jakie interfejs potrafi wyemitować; właśnie dlatego niezasłużony ruch kosztuje tak wiele.
  4. Maskowanie opóźnienia — połysk szkieletu ładowania, optymistyczna podmiana, stopniowe odsłanianie, dzięki któremu 400ms pobierania danych sprawia wrażenie zamierzonych, a nie zepsutych.

Jeśli animacja na ekranie nie wykonuje żadnego z tych czterech zadań, wykonuje piąte: popisuje się.

Cztery pasma czasu trwania

Czasy trwania nie są kwestią gustu; są fizyką dopasowaną do uwagi. Oto pasma, do których przykładam każdy interfejs:

Czas trwania Zastosowanie
~100ms Naciśnięcie przycisku, przełącznik, pole wyboru — potwierdzenie
150-200ms Efekty najechania kursorem, przenikania, dymki podpowiedzi
250-300ms Rozwijanie i zwijanie, akordeon, wsuwane panele
300-400ms Przejścia między stronami, okna modalne, zmiany całej powierzchni

Wzorzec, który leży pod spodem: czas trwania rośnie wraz z rozmiarem zmiany. Kontrolka potwierdzająca naciśnięcie musi reagować niemal natychmiast — powyżej ~150ms potwierdzenie czyta się jako opóźnienie. Przejście pełnoekranowe dostaje więcej czasu, ponieważ użytkownik potrzebuje go, aby się ponownie zorientować. Najczęstszym błędem jest odwrócenie tej zależności: przyciski odbijające się przez 400ms (opóźnienie przebrane za przyjemność) i okna modalne wskakujące w 100ms (dezorientacja przebrana za szybkość).

Powyżej 400ms ruch w interfejsie potrzebuje wyjątkowego powodu, by w ogóle istnieć. Momenty onboardingu i stany świętowania zasługują czasem na 500-600ms; nawigacja w skali telefonu prawie nigdy, choć transformacje kontenerów na dużych ekranach są uczciwym wyjątkiem — powierzchnie tabletów i komputerów zasadnie rozciągają się w stronę 500ms, bo oko ma dalszą drogę do przebycia. Użytkownik uruchamia to przejście tysiące razy, a choreografia, która czarowała na pokazie, jest tarciem, które przeklina w trzecim tygodniu.

Systemy oparte na sprężynach (SwiftUI, Framer Motion) wyrażają czas jako sztywność i tłumienie, a nie jako sztywne wartości, ale pasma nadal obowiązują: opisują postrzegany czas ustabilizowania, do którego się dostraja. Gramatyka przeżywa zmianę notacji.

Dwie reguły easingu

Easing jest tym miejscem, w którym animacja nabiera fizyki, a dwie reguły pokrywają niemal wszystko:

Ease-out dla tego, co wchodzi. Elementy pojawiające się na ekranie startują szybko i zwalniają w miejscu docelowym — lądują. Ease-out przenosi ciężar ruchu na początek, więc oko wcześnie chwyta cel, a element sprawia wrażenie reaktywnego.

Ease-in dla tego, co wychodzi. Elementy odchodzące przyspieszają, oddalając się — wychodzą z zamiarem. Powolny start daje oku moment na zarejestrowanie, że coś odchodzi, zanim zniknie.

Easing linear czyta się jako mechaniczny, bo nic w świecie fizycznym nie porusza się w ten sposób; warto zarezerwować go dla wskaźników postępu, gdzie stałe tempo jest informacją, oraz dla czystych przenikań krycia lub koloru, gdzie nic nie pokonuje odległości i nie ma ruchu, któremu krzywa mogłaby nadać kształt. Symetryczny ease-in-out należy natomiast do trzeciego przypadku, który obie reguły celowo pomijają: do elementów przemieszczających się bez opuszczania ekranu, takich jak zmieniający kolejność wiersz albo zmieniający rozmiar panel. Nie lądują ani nie wychodzą, więc przyspieszają ze spoczynku i z powrotem w nim osiadają. Złą sławę ease-in-out zdobywa jako nieprzemyślana wartość domyślna przy wejściach i wyjściach, bo tam jednocześnie czyni przybycia ociężałymi, a odejścia gwałtownymi.

Test usunięcia w praktyce

Procedura przeglądu, która utrzymuje system ruchu w uczciwości:

  1. Należy zinwentaryzować każdą animację na danej powierzchni — łącznie z domyślnymi ustawieniami frameworka, których nikt świadomie nie wybrał.
  2. Dla każdej trzeba dokończyć zdanie: „Ten ruch mówi użytkownikowi ___”. Pochodzenie przestrzenne, potwierdzenie, uwaga, opóźnienie — jedno z czterech, prostymi słowami.
  3. Cokolwiek zostaje puste, zostaje puste również po dyskusji. „Dodaje dopracowania” i „sprawia wrażenie premium” to puste miejsca o bogatszym słownictwie. Warto usunąć ruch i popatrzeć na powierzchnię przez dzień; dopracowanie, które istniało wyłącznie w ruchu, nigdy dopracowaniem nie było.
  4. To, co przetrwa, należy zmierzyć względem pasm, poprawić easingi i przetestować ścieżkę ograniczonego ruchu. prefers-reduced-motion musi dawać w pełni spójny interfejs złożony z natychmiastowych zmian stanu — jeśli usunięcie animacji psuje zrozumiałość, znaczy to, że animacja niosła informację, która powinna istnieć także statycznie, a to samo w sobie jest ustaleniem.

Po przeprowadzeniu tego na dojrzałym produkcie zwykle ginie połowa inwentarza. Reprezentatywna lista skreśleń z jednego przebiegu: unoszenie kart przy najechaniu kursorem trwające 400ms (nie mówi użytkownikowi niczego, czego nie powiedziała już zmiana kursora), kaskadowe wejście listy odtwarzane przy każdej nawigacji (600ms na ogłoszenie „mamy wiersze”), pulsująca ikona zapisu (uwaga zawłaszczona, a nie zmieniło się nic, czemu warto by ją poświęcić). Nikomu ich nie brakuje. To, co zostaje, staje się szybsze, spójniejsze i — paradoksalnie — bardziej zauważalne, ponieważ ruch odzyskuje wartość sygnału w chwili, gdy przestaje być tłem.

Spojrzenie systemowe

W design systemie ruch mieszka w tokenach dokładnie tak samo jak odstępy i kolor: nazwane czasy trwania (--motion-press: 100ms, --motion-surface: 300ms), nazwane easingi (--ease-enter, --ease-exit) oraz komponenty, które konsumują tokeny, zamiast wymyślać wartości czasowe na miejscu. Trybem awarii nieusystematyzowanego ruchu nie jest brzydota, lecz dryf — pięć okien modalnych z pięcioma czasami trwania, każdy do obrony z osobna, razem niespójne. Ta sama dyscyplina, która rządzi skalą odstępów, rządzi skalą ruchu: każda wartość pochodzi z systemu albo niesie udokumentowany powód.

Ruch jest przy tym najbardziej nietrwałą warstwą design systemu — tą, na której współpracownicy najszybciej działają na własną rękę, bo jednorazowy tween o długości 250ms wydaje się nieszkodliwy. Jest nieszkodliwy jedenaście razy, a potem produkt migocze jedenastoma akcentami nieumotywowanego ruchu. Gramatyka trzyma się tylko tak długo, jak długo test usunięcia pozostaje w użyciu.

Często zadawane pytania

Jak długo powinny trwać animacje interfejsu?

Czas trwania należy dopasować do rozmiaru zmiany: ~100ms na potwierdzenie ze strony kontrolki (naciśnięcia, przełączniki), 150-200ms na najechania kursorem i przenikania, 250-300ms na rozwijanie i zwijanie, 300-400ms na przejścia między stronami i okna modalne. Wszystko powyżej 400ms wymaga wyjątkowego uzasadnienia — użytkownicy powtarzają przejścia interfejsu tysiące razy.

Jakiego easingu powinny używać animacje interfejsu?

Ease-out dla elementów wchodzących (szybki start, zwolnienie w miejscu docelowym), ease-in dla elementów wychodzących (przyspieszenie przy oddalaniu) oraz ease-in-out dla elementów, które przemieszczają się, pozostając na ekranie. Linear warto zarezerwować dla wskaźników postępu i czystych przenikań krycia lub koloru. Przy wejściach linear czyta się mechanicznie, a ease-in-out czyni przybycia ociężałymi — regułą jest ease-out.

Kiedy interfejs powinien w ogóle sięgać po animację?

Wtedy, gdy ruch niesie informację, której statyczna zmiana przekazać nie potrafi: ciągłość przestrzenną (skąd coś przyszło lub dokąd odeszło), potwierdzenie danych wejściowych, kierowanie uwagą ku temu, co się zmieniło, albo maskowanie nieuniknionego opóźnienia. Jeśli nie da się wskazać, które z tych zadań wykonuje dana animacja, trzeba ją usunąć — ruch dekoracyjny opodatkowuje każdą interakcję, której dotyka.

Jak prefers-reduced-motion wpisuje się w system ruchu?

Jako wymaganie pierwszej kategorii: ścieżka ograniczona zastępuje ruch natychmiastowymi zmianami stanu, a interfejs musi pozostać w pełni zrozumiały. Jeśli usunięcie animacji psuje zrozumienie, ruch niósł informację, która potrzebuje statycznego odpowiednika — jest to jednocześnie ustalenie dotyczące dostępności i ustalenie projektowe.

Powiązane artykuły

Kanon formularzy: każde pole to pytanie

Projektowanie formularzy ma swój kanon: jedna kolumna, widoczne etykiety, wyrozumiałe pola, komunikaty błędów, które ucz…

8 min czytania

Ikony to słownik, a nie dekoracja

Ikony interfejsu działają jak język, w którym wszyscy znają mniej więcej tuzin słów. Domyślnie z etykietą, jedna rodzina…

7 min czytania

Filozofia projektowania: Fumito Ueda, projektowanie przez odejmowanie

Fumito Ueda stworzył trzy gry w ciągu dwudziestu lat, usuwając wszystko, co nie służyło jednej emocji. Projektowanie prz…

7 min czytania