chevron-left chevron-right

[CSS] Kilka sposobów na ożywienie interfejsu użytkownika za pomocą animacji CSS

Tworząc różnego rodzaju interfejsy użytkownika na stronach internetowych czy też w aplikacjach internetowych najczęściej skupiamy się na użyteczności. Jest to bardzo ważne, ponieważ nie ma nic gorszego z punktu widzenia użytkownika niż interfejs, który nie pozwala osiągnąć zamierzonego efektu w jak najmniejszej ilości potrzebnych kroków do wykonania.

W tym wpisie, nie będę jednak skupiał się na użyteczności interfejsów. Zamierzam się skupić na przedstawieniu kilku ciekawych efektów, które pozwolą wzbogacić doznania związane z używaniem Twojej aplikacji/strony internetowej. Efekty te będą bazowały na animacjach elementów interfejsu.

Podczas dodawania animacji w swoim projekcie należy pamiętać o tym, aby animacje nie spowalniały akcji wykonywanych przez użytkownika i żeby były przewidywalne. Bardzo ważne z punktu widzenia projektanta UX jest znaczenie animacji, które klarownie wskazują na to czym jest dany element interfejsu i stanowią spójną całość w połączeniu z wybranym elementem strony. Przykładem niespójnego zachowania elementu interfejsu może być skaczące menu, po kliknięciu w jakikolwiek element menu. Użytkownik się nie spodziewa tego typu reakcji interfejsu. Innym przykładem może być źle dobrana animacja pojawiania się elementów na stronie, np. mamy panel wysuwający się z boku a w nim elementy listy domyślnie ukryte. Niespójnym zachowaniem interfejsu będzie dodanie animacji rozwijania elementów listy z kierunku przeciwnego do kierunku wysuwania panelu (tj. panel wysuwa się z lewej strony, to w takim razie dodanie animacji wysuwania elementów listy z prawej strony będzie co najmniej dziwne).

Animacja rozwijanego menu - scale

Temat rozwijanego menu był poruszany wielokrotnie na tym blogu. Tym razem mam zamiar przedstawić prosty acz dość efektowny sposób na rozwijane menu (lub jakiegokolwiek elementu strony).

Zacznijmy od kodu HTML, który będzie reprezentował menu na stronie:

1
2
3
4
5
6
7
8
9
10
11
    <ul>
        <li><a href="#">Blog</a></li>
        <li>
            <a href="#">Kategorie</a>
            <ul>
                <li><a href="#">Kategoria A</a></li>
                <li><a href="#">Kategoria B</a></li>
            </ul>
        </li>
        <li><a href="#">Kontakt</a></li>
    </ul>

I teraz trochę kodu CSS, który doda odpowiednie przejścia między stanami elementów:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
    ul {
        margin: 1rem 0;
        padding: 0;
        display: flex;
        list-style: none;
    }
 
    li {
        position: relative;
        z-index: 1;
        cursor: pointer;
    }
 
    a {
        display: block;
        padding: .5rem;
        transition: background .3s ease-in-out;
    }
 
    ul ul {
        position: absolute;
        z-index: 2;
        display: flex;
        flex-direction: column;
        top: 100%;
        left: 50%;
        width: 100px;
        margin: 0;
        text-align: center;
        /*
         * Cała magia dzieje się tutaj.
         * Ustawiamy efekt przejścia między stanami, który ma trwać 0.3 sekundy
         */
        transition: transform .3s ease-in-out;
        /*
         * Za efekt zwijania/rozwijania menu odpowiada własność scaleY(),
         * która w połączeniu z transform-origin daje efekt wysuwania/chowania się menu
         * z/do górnej krawędzi paska
         */
        transform: scaleY(0) translate(-50%, 0);
        transform-origin: top center;
    }
 
    li:hover ul {
        /*
         * ustawiamy jak ma wyglądać menu po najechaniu kursorem myszki na element menu
         */
        transform: scaleY(1) translate(-50%, 0);
    }
 
    li:hover a,
    li:hover li:hover a {
        background: #ed45a1;
    }
 
    li:hover li a {
        background: none;
    }

Sposób uzyskania przejścia rozwijania/chowania menu opisałem za pomocą komentarzy w kodzie powyżej.

Animacja dodawania i usuwania elementów listy - keyframes

Inną ciekawą rzeczą do której warto dodać animację jest dodawanie/usuwanie elementów z listy. Dzięki temu tego typu interakcja zyska na atrakcyjności i zyska poczucie immersji.

Na potrzeby demo zdefiniujmy sobie kontener na listę oraz przycisk za pomocą którego będziemy dodawać nowe elementy do listy:

1
2
    <ul></ul>
    <button>Dodaj</button>

Następnie, dodajmy odrobinę kodu CSS:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
    ul {
        margin: 0 auto;
        padding: 0;
        width: 50%;
        list-style: none;
    }
 
    li {
        margin: .25rem 0;
        background: red;
        animation: adding .3s 1 ease-in-out;
    }
 
    li.removed {
        animation: removing .3s 1 ease-in-out;
    }
 
    @keyframes adding {
        0% {
            opacity: 0;
            transform: translateX(-100%);
        }
 
        100% {
            opacity: 1;
            transform: translateX(0);
        }
    }
 
    @keyframes removing {
        0% {
            opacity: 1;
            transform: translateX(0);
        }
 
        100% {
            opacity: 0;
            transform: translateX(100%);
        }
    }

To na co warto teraz zwrócić uwagę to fakt, że do uzyskania efektu dodania i usunięcia elementu wykorzystano tym razem animacje CSS bazujące na tzw. ramkach (@keyframes). Ten sam efekt można uzyskać za pomocą animacji przejść stanów (transition).

Rozwiązanie bazujące na animacji ramek jest lepsze od animacji przejść stanu z tego względu, że potrzebujemy tylko jednej dodatkowej klasy w przypadku, gdy usuwamy element z listy. W przypadku animacji przejść stanów potrzebowalibyśmy 2 klas. Jednej dla stanu zerowego i drugiej dodawanej w momencie usuwania.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
    var CLASS_REMOVED = 'removed',
        LI = 'li',
        btn = document.querySelector('button'),
        list = document.querySelector('ul'),
        addItem = function (event) {
            var li;
 
            event.preventDefault();
 
            li = document.createElement(LI);
            li.innerHTML = 'text';
 
            list.appendChild(li);
        },
        removeItem = function (event) {
            if (event.target.tagName.toLowerCase() !== LI) {
                return;
            }
 
            event.target.classList.add(CLASS_REMOVED);
 
            window.setTimeout(function () {
                list.removeChild(event.target);
            }, 300);
        };
 
    list.addEventListener('click', removeItem, false);
    btn.addEventListener('click', addItem, false);

Powyższy kod Javascript jest odpowiedzialny za dodawanie elementów do listy przy pomocy klinięcia w przycisk oraz dodaje funkcjonalność usuwania elementu z listy za pomocą kliknięcia w wybrany element listy.

Podsumowanie

Mam nadzieję, że przedstawione przeze mnie 2 przykłady wykorzystania animacji w interfejsie użytkownika pomogą Ci w tworzeniu niebanalnych stron internetowych i aplikacji internetowych. Dodam tylko, że odbiór wybranej animacji może być różnie odebrany w zależności od wyboru funkcji animującej. W przykładach wykorzystałem funkcję ease-in-out, ale bardzo często warto się pobawić za pomocą niestandardowych funkcji animujących na bazie funkcji cubic-brezier().

Jak zwykle, zapraszam do komentowania i dzielenia się swoimi opiniami, pytaniami i doświadczeniem w komentarzach znajdujących się pod tym wpisem.

  • > W tym wpisie, nie będę jednak skupiał się na użyteczności interfejsów. Zamierzam się skupić na przedstawieniu kilku ciekawych efektów, które pozwolą wzbogacić doznania związane z używaniem Twojej aplikacji/strony internetowej. Efekty te będą bazowały na animacjach elementów interfejsu.

    Googlersi by Cię chyba zlinczowali 😉 W Material Design animacje pełnią bardzo ważną rolę w komunikacji z użytkownikiem (wręcz wyrastają na podstawowy środek informowania usera o stanie aplikacji). Stąd można powiedzieć, że obecnie animacje stają się ważną częścią użyteczności (patrz: model RAIL → https://developers.google.com/web/tools/chrome-devtools/profile/evaluate-performance/rail?hl=en ).

    Wgl mam wrażenie, że w Google nad animacjami siedzi cała armia genialnych (web)devów, którzy wymyślają te wszystkie reguły: RAIL, FLIP (tak, też wynalazek Google 😉 https://aerotwist.com/blog/flip-your-animations/ ), MD itp itd. A to tylko animacje – można sobie wyobrazić, co się dzieje z V8… 😉

  • Być może by mnie „zlinczowali”, ale będę z tym walczył do końca. Bo uważam, że animacje to tylko dodatek zapewniający efekt „wow”. Animacja nie może być celem interfejsu, to tylko środek do osiągnięcia celu. Tyle i aż tyle.
    Masz rację, odnośnie tego że w Google jest wielu ludzi zajmujących się wymyślaniem nowych standardów. Każdy z nich chce stworzyć coś unikalnego i się wybić. Google próbuje skupiać wokół siebie jak najwięcej tzw. „mózgów” i taki jest efekt, że dzięki nim możemy korzystać z różnych mniej lub bardziej użytecznych narzędzi 🙂

  • > Animacja nie może być celem interfejsu, to tylko środek do osiągnięcia celu. Tyle i aż tyle.

    Oczywiście, ale uważam, że można sobie pozwolić na nadanie ważniejszej roli animacjom. Zwłaszcza, że już chyba tylko antyczne witryny i aplikacje webowe animacji nie mają. A mogą one pomóc poprawić choćby perceived performance.

  • „Bardzo ważne z punktu widzenia projektanta UX jest znaczenie animacji, które klarownie wskazują na to czym jest dany element interfejsu i stanowią spójną całość w połączeniu z wybranym elementem strony.”
    Jak dobrze, że o tym wspominasz. Spotkałem się z wieloma stronami, które pod względem UX były tragiczne i przez to traciły swój potencjał i klientów. Nie ma nic bardziej irytującego niż źle stworzone menu i nawigacja na stronie

  • Raoul

    „Kilka sposobów na”. A ile w rzeczywistości autor nam przedstawia? Dwa. I to ma być kilka?