4 nowe funkcje CSS umożliwiające płynne wejście i wyjście

Joey Arhar
Joey Arhar

Ruch to kluczowy element każdego środowiska cyfrowego, który kieruje użytkownika od jednej interakcji do drugiej. Jest jednak kilka luk w płynnych animacjach na platformie internetowej. Te funkcje to m.in. możliwość łatwego animowania animacji wejścia i wyjścia oraz płynnego przejścia do warstwy górnej i z niej w przypadku elementów możliwych do zamknięcia, takich jak okna dialogowe i okna wyskakujące.

Aby uzupełnić te luki, Chrome 116 i 117 zawierają 4 nowe funkcje platformy internetowej, które umożliwiają płynne animacje i przejścia dla określonych elementów.

Cztery nowe funkcje to:

  • Możliwość animowania elementów display i content-visibility na osi czasu klatki kluczowej (od Chrome 116).
  • Właściwość transition-behavior ze słowem kluczowym allow-discrete umożliwia przejście do określonych właściwości, takich jak display (od Chrome 117).
  • Reguła @starting-style do animowania efektów wejścia z display: none do górnej warstwy (od Chrome 117).
  • Właściwość overlay do kontrolowania działania górnej warstwy podczas animacji (od Chrome 117). ## Wyświetlaj animacje w klatkach kluczowych

Od Chrome 116 w regułach klatek kluczowych możesz używać elementów display i content-visibility. Te elementy zmienią się w momencie wystąpienia klatki kluczowej. Nie są wymagane żadne dodatkowe wartości w tym zakresie:

.card {
  animation: fade-out 0.5s forwards;
}

@keyframes fade-out {
  100% {
    opacity: 0;
    display: none;
  }
}

Poprzedni przykład animował przezroczystość na 0 w czasie trwania wynoszącym 0,5 s, a następnie ustawił w wyświetlaniu wartość „none” (brak). Dodatkowo słowo kluczowe forwards dba o to, aby animacja pozostawała w stanie końcowym, więc element, do którego jest stosowana, pozostaje display: none i opacity: 0.

To jest prosty przykład, który naśladuje to, co możesz zrobić z przejściem (zobacz demonstrację w sekcji dotyczącej przejścia). Przejścia nie mogą jednak tworzyć bardziej złożonych animacji, takich jak:

.card {
  animation: spin-and-delete 1s ease-in forwards;
}

@keyframes spin-and-delete {
  0% {
    transform: rotateY(0);
    filter: hue-rotate(0);
  }
  80% {
    transform: rotateY(360deg);
    filter: hue-rotate(180deg);
    opacity: 1;
  }
  100% {
    opacity: 0;
    display: none;
  }
}

Animacja spin-and-delete to animacja wyjścia. Najpierw karta będzie obracać się wokół osi Y, następnie cyklicznie obracać się barwami, a następnie zmieniać przezroczystość (80%) na osi czasu z 1 na 0. Na koniec karta zostanie zmieniona z display: block na display: none.

Zamiast stosować je bezpośrednio do elementu, możesz skonfigurować ich regułę. Jeśli na przykład dołączysz odbiornik do przycisku, który będzie uruchamiał klasę w celu zastosowania animacji, w ten sposób:

.spin-out {
   animation: spin-and-delete 1s ease-in forwards;
}
document.querySelector('.delete-btn').addEventListener('click', () => {
 document.querySelector('.card').classList.add('spin-out');
})

W przykładzie powyżej element końcowy ma teraz wartość display:none. W wielu przypadkach warto zrobić to dalej i usunąć węzeł DOM z limitem czasu, aby umożliwić wcześniejsze zakończenie animacji.

Przejścia dyskretnych animacji

W odróżnieniu od animacji właściwości dyskretnych za pomocą klatek kluczowych, aby przenieść właściwości dyskretne, musisz użyć trybu zachowania przejścia allow-discrete.

Właściwość transition-behavior

Tryb allow-discrete umożliwia dyskretne przejścia. Jest to wartość właściwości transition-behavior. transition-behavior akceptuje 2 wartości: normal i allow-discrete.

.card {
  transition: opacity 0.25s, display 0.25s;
  transition-behavior: allow-discrete; /* Note: be sure to write this after the shorthand */
}

.card.fade-out {
  opacity: 0;
  display: none;
}
Uwaga: ta prezentacja przejścia przedstawia inną technikę niż pierwsza prezentacja animacji, ale wizualnie wygląda podobnie.

Parametr transition również ustawia tę wartość, więc możesz pominąć tę właściwość i użyć słowa kluczowego allow-discrete na końcu krótkiego opisu funkcji transition.

.card {
  transition: opacity 0.5s, display 0.5s allow-discrete;
}

.card.fade-out {
  opacity: 0;
  display: none;
}

Jeśli animujesz kilka właściwości dyskretnych, musisz dodać allow-discrete po każdej z nich, którą chcesz animować. Na przykład:

.card {
  transition: opacity 0.5s, display 0.5s allow-discrete, overlay 0.5s allow-discrete;
}

.card.fade-out {
  opacity: 0;
  display: none;
}

Reguła @starting-style dotycząca animacji wpisu

Do tej pory w tym artykule omówiliśmy animacje wyjścia. Aby utworzyć takie animacje, musisz użyć reguły @starting-style.

Użyj właściwości @starting-style, aby zastosować styl, który przeglądarka może wyszukać, zanim element zostanie otwarty na stronie. Jest to stan „przed otwarciem” (skąd otwiera się animacja).

/*  0. BEFORE-OPEN STATE   */
/*  Starting point for the transition */
@starting-style {
  .item {
    opacity: 0;
    height: 0;
  }
}

/*  1. IS-OPEN STATE   */
/*  The state at which the element is open + transition logic */
.item {
  height: 3rem;
  display: grid;
  overflow: hidden;
  transition: opacity 0.5s, transform 0.5s, height 0.5s, display 0.5s allow-discrete;
}

/*  2. EXITING STATE   */
/*  While it is deleting, before DOM removal in JS, apply this
    transformation for height, opacity, and a transform which
    skews the element and moves it to the left before setting
    it to display: none */
.is-deleting {
  opacity: 0;
  height: 0;
  display: none;
  transform: skewX(50deg) translateX(-25vw);
}

Teraz masz zarówno stan wejścia, jak i wyjścia dla tych pozycji na liście zadań do wykonania:

Animowanie elementów do i z górnej warstwy

Aby animować elementy do i z górnej warstwy, w stanie „otwarta” określ @starting-style, aby wskazać przeglądarce miejsce animacji. W przypadku okna stan otwarty jest zdefiniowany za pomocą atrybutu [open]. Aby wyświetlić wyskakujące okienko, użyj pseudoklasy :popover-open.

Prosty przykład okna dialogowego może wyglądać tak:

/*   0. BEFORE-OPEN STATE   */
@starting-style {
  dialog[open] {
    translate: 0 100vh;
  }
}

/*   1. IS-OPEN STATE   */
dialog[open] {
  translate: 0 0;
}

/*   2. EXIT STATE   */
dialog {
  transition: translate 0.7s ease-out, overlay 0.7s ease-out allow-discrete, display 0.7s ease-out allow-discrete;
  translate: 0 100vh;
}

W następnym przykładzie efekty wejścia i wyjścia różnią się od siebie. Aby wejść, animuj widoczny obszar w górę, ustaw efekt na górze widocznego obszaru. Jest on również napisany za pomocą zagnieżdżonego kodu CSS, który zapewnia pełniejszy obraz.

Podczas animowania wyskakującego okienka użyj pseudoklasy :popover-open zamiast poprzednio użytego atrybutu open.

.settings-popover {
  &:popover-open {
    /*  0. BEFORE-OPEN STATE  */
    /*  Initial state for what we're animating *in* from, 
        in this case: goes from lower (y + 20px) to center  */
    @starting-style {
      transform: translateY(20px);
      opacity: 0;
    }
    
    /*  1. IS-OPEN STATE  */
    /*  state when popover is open, BOTH:
        what we're transitioning *in* to 
        and transitioning *out* from */
    transform: translateY(0);
    opacity: 1;
  }
  
  /*  2. EXIT STATE  */
  /*  Initial state for what we're animating *out* to , 
      in this case: goes from center to (y - 50px) higher */
  transform: translateY(-50px);
  opacity: 0;
  
  /*  Enumerate transitioning properties, 
      including display and allow-discrete mode */
  transition: transform 0.5s, opacity 0.5s, display 0.5s allow-discrete;
}

overlay miejsce zakwaterowania

Na koniec, aby zanikać z górnej warstwy, dodaj właściwość overlay do listy przejść (popover lub dialog). Zmienne i klipy elementów nadrzędnych w elementach popover i dialog są kopiowane i przekształcane, a treści są umieszczane w górnej warstwie. Jeśli nie przeniesiesz elementu overlay, element zostanie natychmiast skrócony, przekształcony i zasłonięty. Przejście nie będzie widoczne.

[open] {
  transition: opacity 1s, display 1s allow-discrete;
}

Zamiast tego dodaj element overlay w przejściu lub animacji, aby animować element overlay wraz z pozostałymi funkcjami. Po jego zakończeniu animowany element pozostanie na górze warstwy. Wygląda to dużo płynniej.

[open] {
  transition: opacity 1s, display 1s allow-discrete, overlay 1s allow-discrete;
}

Poza tym, gdy w górnej warstwie jest otwartych wiele elementów, nakładka pomaga kontrolować płynne przejście do i poza nią. Różnicę widać w tym prostym przykładzie. Jeśli nie zastosujesz efektu overlay do drugiego wyskakującego okienka podczas jego przenoszenia, przed rozpoczęciem przejścia najpierw opuści ono górną warstwę, przeskakując za drugie wyskakujące okienko. Nie jest to bardzo płynny efekt.

Uwaga na temat przenoszenia widoków

Jeśli wprowadzasz zmiany DOM, np. dodajesz i usuwasz elementy DOM, kolejnym doskonałym rozwiązaniem dla płynnych animacji są przejścia widoku. Oto dwa z powyższych przykładów stworzonych z wykorzystaniem przejść widoku.

W pierwszej wersji demonstracyjnej zamiast konfigurowania @starting-style i innych przekształceń CSS przejściem zajmie się przejść do widoku danych. Przejście do widoku jest skonfigurowane w ten sposób:

Najpierw w CSS nadaj każdej karcie indywidualne view-transition-name.

.card-1 {
  view-transition-name: card-1;
}

.card-2 {
  view-transition-name: card-2;
}

/* etc. */

Następnie w JavaScript zapakuj mutację DOM (w tym przypadku usuwając kartę) w przejście widoku.

deleteBtn.addEventListener('click', () => {
  // Check for browser support
  if (document.startViewTransition) {
    document.startViewTransition(() => {
      // DOM mutation
      card.remove();
    });
  } 
  // Alternative if no browser support
  else {
    card.remove();
  }
})

Teraz przeglądarka może obsłużyć zanikanie i przekształcenie każdej karty w nowym miejscu.

Kolejnym przykładem, w którym może się to przydać, jest prezentacja elementów listy dodawania/usuwania. W takim przypadku musisz dodać unikalny identyfikator view-transition-name do każdej utworzonej karty.

Podsumowanie

Te nowe funkcje platformy przybliżają nas o krok do płynnego wejścia i wyjścia w internecie. Więcej informacji znajdziesz na tych stronach: