ToolHub
View All Posts

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

ScenariuszUżyj przejściaUżyj animacji
Efekt hoverTakNie
Stan focusTakNie
Przełączanie widocznościTakMożliwe
Sekwencja wieloetapowaNieTak
Animacja zapętlonaNieTak
Niezależna od stanuNieTak
Animacja wejściaMożliweTak

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:

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

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:

  1. Styl: określa, które reguły CSS mają zastosowanie do których elementów.
  2. 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.
  3. Malowanie: wypełnia piksele dla każdego elementu. Wyzwalane przez zmiany color, background, box-shadow, border-radius i innych właściwości wizualnych.
  4. 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?
transformNieNieTak
opacityNieNieTak
filterNieTakCzasami
top / leftTakTakNie
width / heightTakTakNie
margin / paddingTakTakNie
background-colorNieTakNie
box-shadowNieTakNie

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:

Zasada wydajności: jeśli możesz osiągnąć ten sam efekt wizualny za pomocą transform lub opacity, zawsze preferuj je zamiast właściwości wyzwalających układ lub malowanie. Ta zasada może wyeliminować większość problemów z wydajnością animacji.

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:

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

Biblioteki animacji JavaScript

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:

Analiza wydajności

Użyj panelu Performance w Chrome DevTools, aby zidentyfikować zacięcia animacji:

Typowe scenariusze debugowania

Pracujesz z CSS? Wypróbuj nasze darmowe narzędzia CSS do formatowania, kompresji i optymalizacji arkuszy stylów do produkcji.

Formatter CSSMinifikator CSS

FAQ

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.