Przewodnik po animacjach CSS: Przejścia, klatki kluczowe i wydajność
Animacje CSS ożywiają interfejsy, zapewniając wizualną informację zwrotną, kierując uwagą użytkownika i tworząc niezapomniane doświadczenia. Dobrze wykonane animacje wydają się naturalne i intuicyjne; źle wykonane powodują zacinań, rozpraszają użytkowników, a nawet wywołują fizyczny dyskomfort. Ten przewodnik obejmuje wszystko, od podstaw przejść i klatek kluczowych po zaawansowaną optymalizację wydajności i dostępność, dając ci wiedzę do tworzenia płynnych, celowych i inkluzywnych animacji.
Przejścia i animacje CSS
CSS oferuje dwa odrębne mechanizmy tworzenia efektów ruchu: przejścia i animacje. Zrozumienie, kiedy używać każdego z nich, jest podstawą efektywnej pracy z animacjami CSS.
Przejścia CSS
Przejścia animują zmiany między dwoma stanami właściwości CSS. Definiujesz właściwości do animowania, czas trwania animacji i krzywą wygładzania, a przeglądarka automatycznie obsługuje interpolację między wartościami początkowymi i końcowymi. Przejścia są wyzwalane przez zmiany stanu, takie jak hover, focus, dodanie klasy lub zmiana właściwości JavaScript.
.button {
background: #3b82f6;
transform: scale(1);
transition: background 0.3s ease, transform 0.2s ease;
}
.button:hover {
background: #2563eb;
transform: scale(1.05);
}Przejścia są idealne do prostych animacji dwustanowych. Wymagają minimalnej ilości kodu, są łatwe do zrozumienia i niezawodnie działają w przeglądarkach. Ograniczeniem jest to, że animują tylko między dwiema wartościami — nie można definiować kroków pośrednich.
Animacje CSS (klatki kluczowe)
Animacje używają reguły @keyframes do definiowania sekwencji zmian stylu w dowolnej liczbie kroków. W przeciwieństwie do przejść, animacje mogą działać niezależnie od zmian stanu, zapętlać się w nieskończoność, odtwarzać wstecz i wstrzymywać. Dają precyzyjną kontrolę nad każdą klatką animacji.
@keyframes pulse {
0% {
transform: scale(1);
opacity: 1;
}
50% {
transform: scale(1.05);
opacity: 0.8;
}
100% {
transform: scale(1);
opacity: 1;
}
}
.pulse-element {
animation: pulse 2s ease-in-out infinite;
}Kiedy używać którego
| Scenariusz | Użyj przejścia | Użyj animacji |
|---|---|---|
| Efekt hover | Tak | Nie |
| Stan focus | Tak | Nie |
| Przełączanie widoczności | Tak | Możliwe |
| Sekwencja wieloetapowa | Nie | Tak |
| Animacja zapętlona | Nie | Tak |
| Niezależna od stanu | Nie | Tak |
| Animacja wejścia | Możliwe | Tak |
Szczegółowa analiza składni klatek kluczowych
Reguła @keyframes jest sercem animacji CSS. Pełne zrozumienie jej składni uwalnia pełną moc wieloetapowych sekwencji animacji.
Klatki kluczowe oparte na procentach
Klatki kluczowe są definiowane przy użyciu wartości procentowych od 0% do 100%, reprezentujących postęp na osi czasu animacji. Możesz zdefiniować tyle klatek kluczowych, ile potrzebujesz, a przeglądarka interpoluje między nimi:
@keyframes bounce {
0%, 100% {
transform: translateY(0);
}
25% {
transform: translateY(-20px);
}
50% {
transform: translateY(0);
}
75% {
transform: translateY(-10px);
}
}Wiele klatek kluczowych może współdzielić ten sam blok stylów, oddzielając wartości procentowe przecinkami, jak 0%, 100% w powyższym przykładzie. Jest to przydatne w przypadku animacji, które wracają do stanu początkowego.
Właściwość skrócona animacji
Właściwość skrócona animation łączy osiem podwłaściwości w jedną deklarację. Kolejność to: name, duration, timing-function, delay, iteration-count, direction, fill-mode i play-state.
.element {
animation: slideIn 0.5s ease-out 0.2s 1 forwards running;
}
/* Equivalent longhand */
.element {
animation-name: slideIn;
animation-duration: 0.5s;
animation-timing-function: ease-out;
animation-delay: 0.2s;
animation-iteration-count: 1;
animation-direction: normal;
animation-fill-mode: forwards;
animation-play-state: running;
}Tryb wypełniania animacji
Właściwość animation-fill-mode kontroluje, które style są stosowane przed i po uruchomieniu animacji. To jedna z najczęściej źle rozumianych właściwości animacji:
- none (domyślnie): Element powraca do stylu sprzed animacji po jej zakończeniu.
- forwards: Po zakończeniu animacji element zachowuje styl ostatniej klatki. Kluczowe dla animacji wejścia, gdzie element ma pozostać w swojej końcowej pozycji.
- backwards: Podczas opóźnienia animacji (przed jej rozpoczęciem) element stosuje styl pierwszej klatki.
- both: Łączy zachowanie forwards i backwards. Element wyświetla pierwszą klatkę podczas opóźnienia i zachowuje ostatnią klatkę po zakończeniu.
Funkcja wyg\u0142adzania
Funkcje wygładzania (nazywane również funkcjami czasu) definiują krzywą przyspieszenia animacji. Określają, czy animacja zaczyna się powoli i przyspiesza, zaczyna szybko i zwalnia, czy podąża za bardziej złożonym wzorcem. Prawidłowa funkcja wygładzania sprawia, że animacja wydaje się naturalna; nieprawidłowa sprawia, że wydaje się mechaniczna lub szarpana.
Wbudowane funkcje wygładzania
- linear: Stała prędkość przez cały czas trwania animacji. Rzadko wygląda naturalnie, ponieważ obiekty w rzeczywistym świecie nie poruszają się ze stałą prędkością. Odpowiedni dla animacji mechanicznych lub obrotowych.
- ease (domyślne): Zaczyna powoli, przyspiesza w środku, zwalnia na końcu. Dobre uniwersalne wygładzanie dla większości przejść UI.
- ease-in: Zaczyna powoli, potem przyspiesza. Tworzy wrażenie "nabierania rozpędu". Odpowiedni dla elementów opuszczających ekran lub spadających.
- ease-out: Zaczyna szybko, potem zwalnia. Tworzy wrażenie "osiadania na miejscu". Najczęściej używane wygładzanie dla elementów UI wchodzących na ekran.
- ease-in-out: Powolny początek i koniec, szybszy w środku. Podobny do ease, ale z wyraźniejszym przyspieszaniem i zwalnianiem. Odpowiedni dla większych, bardziej dramatycznych przejść.
Krzywa Beziera trzeciego stopnia
Funkcja cubic-bezier() pozwala definiować niestandardowe krzywe wygładzania z precyzyjną kontrolą. Przyjmuje cztery parametry reprezentujące punkty kontrolne krzywej Beziera trzeciego stopnia: cubic-bezier(x1, y1, x2, y2). Wartości x reprezentują czas (0 do 1), wartości y reprezentują postęp (mogą przekraczać 0-1 dla efektów przeregulowania).
.element {
/* Smooth deceleration - great for entrances */
transition: transform 0.3s cubic-bezier(0.0, 0.0, 0.2, 1.0);
/* Smooth acceleration - great for exits */
transition: transform 0.2s cubic-bezier(0.4, 0.0, 1, 1);
/* Material Design standard easing */
transition: transform 0.3s cubic-bezier(0.4, 0.0, 0.2, 1);
}Funkcja schodkowa
Funkcja steps() tworzy dyskretne animacje klatka po klatce zamiast płynnej interpolacji. Jest to przydatne dla animacji sprite'ów lub tworzenia efektu "pisania":
@keyframes typing {
from { width: 0; }
to { width: 100%; }
}
.typing-effect {
animation: typing 3s steps(40, end);
overflow: hidden;
white-space: nowrap;
}Optymalizacja wydajności
Płynne animacje wymagają osiągnięcia 60 klatek na sekundę (fps), co oznacza, że każda klatka musi być ukończona w ciągu 16,67 milisekundy. Nieosiągnięcie tego budżetu powoduje widoczne zacięcia — drganie, gubienie klatek i pogorszenie doświadczenia użytkownika. Zrozumienie potoku renderowania przeglądarki jest kluczem do pisania wydajnych animacji.
Potok renderowania
Gdy zmienia się właściwość CSS, przeglądarka przechodzi przez maksymalnie trzy fazy, aby zaktualizować wyświetlacz:
- Styl: określa, które reguły CSS mają zastosowanie do których elementów.
- Układ: oblicza rozmiar i pozycję każdego elementu. Wyzwalany przez zmiany width, height, margin, padding, top, left, font-size i innych właściwości geometrycznych.
- Malowanie: wypełnia piksele dla każdego elementu. Wyzwalane przez zmiany color, background, box-shadow, border-radius i innych właściwości wizualnych.
- Kompozycja: łączy pomalowane warstwy w odpowiedniej kolejności. Tylko ten krok działa na GPU. Wyzwalany przez zmiany transform i opacity.
Animacje, które wyzwalają tylko krok kompozycji, działają najlepiej, ponieważ całkowicie pomijają układ i malowanie. Dlatego transform i opacity są złotym standardem dla wydajnych animacji CSS.
Właściwości tylko kompozytora
| Właściwość | Wyzwala układ? | Wyzwala malowanie? | Kompozycja GPU? |
|---|---|---|---|
| transform | Nie | Nie | Tak |
| opacity | Nie | Nie | Tak |
| filter | Nie | Tak | Czasami |
| top / left | Tak | Tak | Nie |
| width / height | Tak | Tak | Nie |
| margin / padding | Tak | Tak | Nie |
| background-color | Nie | Tak | Nie |
| box-shadow | Nie | Tak | Nie |
Używanie will-change
Właściwość will-change mówi przeglądarce, które właściwości mają się zmienić, pozwalając jej zoptymalizować z wyprzedzeniem poprzez przeniesienie elementu na własną warstwę kompozytora. Należy jej jednak używać ostrożnie:
/* Apply will-change just before the animation */
.element:hover {
will-change: transform;
}
/* Remove it after the animation completes */
.element {
transition: transform 0.3s ease;
}Typowe błędy z will-change obejmują stosowanie go do zbyt wielu elementów (każda warstwa kompozytora zużywa pamięć GPU) i pozostawianie go na stałe (marnowanie zasobów). Dobrą praktyką jest dodawanie will-change przez JavaScript przed rozpoczęciem animacji i usuwanie go po zakończeniu.
Używaj Transform zamiast właściwości układu
Najskuteczniejszą optymalizacją wydajności jest zastąpienie właściwości wyzwalających układ przez transform:
- Użyj transform: translateX(100px) zamiast left: 100px
- Użyj transform: translateY(50px) zamiast top: 50px
- Użyj transform: scale(1.5) zamiast width: 150%; height: 150%
- Użyj transform: rotate(45deg) zamiast rotacji przez układ
Typowe wzorce animacji
Pewne wzorce animacji pojawiają się wielokrotnie w interfejsach internetowych. Opanowanie tych wzorców daje Ci zestaw narzędzi do większości typowych potrzeb animacji UI.
1. Przenikanie
Najprostsza i najbardziej wszechstronna animacja wejścia. Element przechodzi od przezroczystego do nieprzezroczystego:
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
.fade-in {
animation: fadeIn 0.4s ease-out forwards;
}2. Przesunięcie w górę z przenikaniem
Bardziej dynamiczny efekt wejścia, łączący ruch pionowy ze zmianą przezroczystości. Tworzy to wrażenie, że element przybywa z dołu:
@keyframes slideUpFade {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.slide-up {
animation: slideUpFade 0.5s cubic-bezier(0.4, 0, 0.2, 1) forwards;
}3. Skalowanie przy najechaniu
Subtelne zwiększenie skali przy najechaniu zapewnia satysfakcjonujące sprzężenie zwrotne interakcji:
.card {
transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.card:hover {
transform: translateY(-4px) scale(1.02);
box-shadow: 0 12px 24px rgba(0, 0, 0, 0.15);
}4. Animacje list naprzemiennych
Gdy pojawia się lista elementów, ustawienie naprzemiennych opóźnień animacji dla każdego elementu tworzy efekt kaskadowy, który prowadzi wzrok:
.list-item {
opacity: 0;
transform: translateY(10px);
animation: slideUpFade 0.3s ease-out forwards;
}
.list-item:nth-child(1) { animation-delay: 0.0s; }
.list-item:nth-child(2) { animation-delay: 0.05s; }
.list-item:nth-child(3) { animation-delay: 0.1s; }
.list-item:nth-child(4) { animation-delay: 0.15s; }
.list-item:nth-child(5) { animation-delay: 0.2s; }W przypadku list dynamicznych użyj JavaScript, aby ustawić animation-delay na podstawie indeksu każdego elementu, lub użyj niestandardowych właściwości CSS: style="animation-delay: calc(var(--i) * 0.05s)".
5. Animacja ładowania
Płynny, ciągły obrót to klasyczny wskaźnik ładowania:
@keyframes spin {
to { transform: rotate(360deg); }
}
.spinner {
width: 24px;
height: 24px;
border: 3px solid rgba(255, 255, 255, 0.2);
border-top-color: #3b82f6;
border-radius: 50%;
animation: spin 0.8s linear infinite;
}Dostępność animacji: prefers-reduced-motion
Nie wszyscy użytkownicy korzystają z animacji. Dla osób z zaburzeniami przedsionkowymi, wrażliwością na ruch lub pewnymi schorzeniami poznawczymi, animacje mogą powodować zawroty głowy, nudności lub drgawki. Zapytanie media prefers-reduced-motion pozwala respektować preferencje użytkownika dotyczące redukcji animacji na poziomie systemu.
Implementacja redukcji animacji
Zalecanym podejściem jest włączanie animacji dla użytkowników, którzy nie ustawili preferencji redukcji animacji:
/* Default: no animation for users who prefer reduced motion */
.element {
opacity: 1;
transform: none;
}
/* Only animate for users who have no motion preference */
@media (prefers-reduced-motion: no-preference) {
.element {
animation: slideUpFade 0.5s ease-out forwards;
}
}Alternatywnie możesz wyłączyć określone animacje dla użytkowników preferujących redukcję animacji:
.element {
animation: slideUpFade 0.5s ease-out forwards;
}
@media (prefers-reduced-motion: reduce) {
.element {
animation: none;
opacity: 1;
transform: none;
}
/* Keep functional transitions but shorten duration */
* {
animation-duration: 0.01ms !important;
transition-duration: 0.01ms !important;
}
}Co zachować, a co usunąć
Gdy użytkownik preferuje redukcję animacji, nie wszystkie animacje powinny być usuwane. Funkcjonalne animacje, które przekazują znaczenie lub stan, powinny zostać zachowane, tylko uproszczone:
- Usuń: animacje dekoracyjne, przewijanie paralaksy, automatycznie odtwarzane karuzele, efekty pulsowania i zapętlone animacje tła.
- Uprość: czasy trwania przejść powinny być skrócone do prawie natychmiastowych (0,01ms) zamiast całkowicie usuwane, aby zmiany stanu były nadal dostrzegalne.
- Zachowaj: funkcjonalne przejścia stanów (hover, focus, stan aktywny), wskaźniki postępu i wszelkie animacje, które przekazują ważne informacje.
Biblioteki animacji
Chociaż animacje CSS obsługują większość potrzeb UI, biblioteki animacji JavaScript oferują zaawansowane funkcje, takie jak ruch oparty na fizyce, animacje powiązane z przewijaniem i orkiestrację złożonych sekwencji.
Biblioteki z priorytetem CSS
- Animate.css: Kolekcja gotowych klas animacji CSS. Wystarczy dodać nazwę klasy do elementu, aby zastosować animację. Świetne do szybkiego prototypowania, ale może prowadzić do powtarzalnych efektów ruchu przy nadmiernym użyciu.
- Hamburgers: Kolekcja animowanych przejść ikon menu hamburgerowego, wszystkie zaimplementowane w czystym CSS.
Biblioteki animacji JavaScript
- Framer Motion: Biblioteka animacji React oferująca deklaratywne API animacji z obsługą fizyki sprężynowej, animacji układu i gestów. Najlepszy wybór dla aplikacji React.
- GSAP (GreenSock): Najpotężniejsza biblioteka animacji JavaScript. Oferuje precyzyjną kontrolę osi czasu, złożone wygładzanie, morfing SVG i animacje wyzwalane przewijaniem. Używana przez duże marki do stron marketingowych i interaktywnych doświadczeń.
- Anime.js: Lekka biblioteka animacji JavaScript z czystym API. Obsługuje właściwości CSS, SVG, właściwości DOM i obiekty JavaScript. Dobry wybór pośredni między CSS a GSAP.
- Motion One: Nowoczesna, lekka biblioteka animacji zbudowana na Web Animations API. Oferuje minimalne API z obsługą fizyki sprężynowej i osi czasu.
Kiedy używać JavaScript vs CSS
CSS: Proste, deklaratywne animacje reagujące na zmiany stanu. JavaScript: Ruch oparty na fizyce (sprężyny, pęd), animacje powiązane z przewijaniem, złożone sekwencje z precyzyjną kontrolą czasu, dynamiczne parametry animacji obliczane w czasie wykonania lub animacje, które wymagają programowego wstrzymywania, odwracania lub przeciągania.
Debugowanie animacji
Błędy animacji mogą być subtelne i trudne do zdiagnozowania. Odpowiednie narzędzia i techniki debugowania sprawiają, że proces jest bardziej wydajny.
Panel animacji Chrome DevTools
Chrome DevTools zawiera dedykowany panel animacji z potężnymi możliwościami debugowania:
- Widok osi czasu: przeglądaj wszystkie aktywne animacje na stronie wraz z ich czasem trwania, opóźnieniami i klatkami kluczowymi.
- Kontrola odtwarzania: spowolnij animacje do 1/4 prędkości, wstrzymaj lub przeciągaj oś czasu klatka po klatce.
- Inspekcja właściwości: kliknij animację na osi czasu, aby zobaczyć dokładne właściwości CSS, które są animowane, i ich wartości w każdej klatce kluczowej.
- Edycja na żywo: modyfikuj czas trwania animacji, opóźnienia i wygładzanie w czasie rzeczywistym bez przeładowywania strony.
Analiza wydajności
Użyj panelu Performance w Chrome DevTools, aby zidentyfikować zacięcia animacji:
- Nagraj ślad wydajności podczas działania animacji
- Znajdź klatki przekraczające budżet 16,67ms (pokazane jako czerwone paski na wykresie klatek)
- Sprawdź, czy w klatkach animacji występują operacje „Layout”, które wskazują na właściwości wyzwalające układ
- Użyj zakładki „Rendering”, aby włączyć „Paint flashing” (pokazuje obszary przemalowania na zielono) i „Layer borders” (pokazuje warstwy kompozytora)
Typowe scenariusze debugowania
- Animacja nie działa: sprawdź, czy animation-fill-mode jest ustawione prawidłowo. Bez forwards lub both element wraca do stanu sprzed animacji. Zweryfikuj również, czy element ma prawidłowe wymiary — transform: scale(0) sprawia, że element jest niewidoczny, ale nadal istnieje.
- Zacinanie się animacji: otwórz panel Performance, aby znaleźć długie klatki. Sprawdź, czy animujesz właściwości wyzwalające układ. Przełącz się na transform i opacity.
- Opóźnienie animacji wydaje się nieprawidłowe: pamiętaj, że animation-delay tworzy odstęp przed rozpoczęciem animacji. Podczas tego odstępu element wyświetla stan sprzed animacji, chyba że ustawiono animation-fill-mode: backwards lub both.
- Animacja działa w Chrome, ale nie w Safari: Safari ma bardziej rygorystyczne parsowanie skrótu animation. Upewnij się, że wszystkie wartości są we właściwej kolejności i nie używasz nieobsługiwanych funkcji.
Pracujesz z CSS? Wypróbuj nasze darmowe narzędzia CSS do formatowania, kompresji i optymalizacji arkuszy stylów do produkcji.
Formatter CSSMinifikator CSSFAQ
Czy powinienem używać przejść CSS czy animacji CSS?
Przejścia CSS służą do prostych zmian stanu z punktu A do B, takich jak efekty najechania, stany fokusu i przełączanie widoczności. Animacje CSS (klatki kluczowe) służą do złożonych sekwencji wieloetapowych, animacji zapętlonych lub animacji, które muszą działać niezależnie od zmian stanu. Przejścia są prostsze; animacje oferują większą kontrolę.
Które właściwości CSS można bezpiecznie animować dla wydajności?
Najlepszymi właściwościami do wydajności animacji są transform i opacity, ponieważ mogą być w całości obsługiwane przez kompozytor GPU bez wyzwalania układu lub malowania. Inne właściwości, takie jak width, height, margin i top, wyzwalają ponowne obliczanie układu, co jest kosztowne. Zawsze preferuj transform: translateX() zamiast left i transform: scale() zamiast zmian width/height.
Jak zapewnić dostępność dla użytkowników wrażliwych na animacje?
Użyj zapytania media prefers-reduced-motion, aby wyłączyć lub uprościć animacje dla użytkowników, którzy włączyli ustawienie „redukcji animacji” w systemie operacyjnym. Opakuj nieistotne animacje w @media (prefers-reduced-motion: no-preference) i zapewnij natychmiastowe zmiany stanu jako fallback dla użytkowników preferujących redukcję animacji.
Czym jest will-change i kiedy należy go używać?
will-change to właściwość CSS, która informuje przeglądarkę, które właściwości zmienią się w przyszłości, pozwalając jej zoptymalizować z wyprzedzeniem. Używaj ostrożnie, tylko gdy zaobserwujesz problemy z wydajnością. Stosuj przed rozpoczęciem animacji i usuwaj po jej zakończeniu. Nadmierne używanie will-change marnuje pamięć GPU i może faktycznie zaszkodzić wydajności.
Jak debugować animacje CSS?
Chrome DevTools oferuje potężne narzędzia do debugowania animacji. Otwórz panel animacji (w menu Więcej narzędzi), aby zobaczyć wszystkie aktywne animacje, przeciągać linię czasu, modyfikować czas trwania i opóźnienia w czasie rzeczywistym oraz spowalniać animacje do 1/4 prędkości. Możesz również użyć panelu Performance do identyfikacji zacinania się animacji i drgania układu.