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

Ruch to podstawowy element wszystkich usług cyfrowych, który prowadzi użytkownika od jednej interakcji do drugiej. Na platformie internetowej występują jednak pewne przerwy w płynnych animacjach. Obejmują one możliwość łatwego animowania animacji wejścia i wyjścia oraz płynne animowanie do i z górnej warstwy w przypadku elementów, które można zamknąć, takich jak okna czy wyskakujące okienka.

Aby wypełnić te luki, w Chrome 116 i 117 znajdziesz 4 nowe funkcje platformy internetowej, które umożliwiają płynne animacje i przejścia w przypadku oddzielnych usług.

Te 4 nowe funkcje to:

  • Możliwość animowania display i content-visibility na osi czasu klatki kluczowej (od Chrome 116).
  • Właściwość transition-behavior z kluczowym słowem allow-discrete, aby umożliwić przejścia z osobnych właściwości, takich jak display (z Chrome 117).
  • Reguła @starting-style służąca do animowania efektów wejścia z poziomu display: none do najwyższej warstwy (z Chrome 117).
  • Właściwość overlay umożliwia kontrolowanie zachowania najwyższej warstwy podczas animacji (od Chrome 117).

Wyświetlanie animacji w klatkach kluczowych

Od wersji 116 przeglądarki Chrome możesz używać w regułach kluczowych klatek wartości displaycontent-visibility. Następnie zostaną one zastąpione w momencie wystąpienia klatki kluczowej. Nie trzeba dodawać żadnych nowych wartości, aby obsługiwać te funkcje:

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

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

W poprzednim przykładzie przezroczystość jest animowana do wartości 0 w ciągu 0,5 s, a potem ustawiana na wartość 0. Dodatkowo słowo kluczowe forwards sprawia, że animacja pozostaje w stanie końcowym, dzięki czemu element, do którego jest zastosowana, pozostaje w pozycji display: noneopacity: 0.

To prosty przykład, który pokazuje, co możesz zrobić z przejściem (zobacz wersję demonstracyjną w sekcji Przejście). Przejścia nie są jednak w stanie utworzyć bardziej złożonych animacji, jak w tym przykładzie:

.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 zakończenia. Najpierw karta będzie się obracać wokół osi y, a następnie będzie przechodzić przez kolejne odcienie. Następnie w 80% na osi czasu jej przezroczystość będzie się zmieniać od 1 do 0. W końcu karta zmienia się z display: block na display: none.

Zamiast stosować te animacje bezpośrednio do elementu, możesz skonfigurować dla nich wyzwalacz. Możesz to zrobić na przykład, dołączając detektor zdarzeń do przycisku, który uruchamia klasę, aby zastosować animację.

.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 stan końcowy to display:none. W wielu przypadkach warto usunąć węzeł DOM z czasem oczekiwania, aby najpierw zakończyła się animacja.

Przechodzenie między poszczególnymi animacjami

W przeciwieństwie do animacji właściwości dyskretnych za pomocą klatek kluczowych, aby przekształcać właściwości dyskretne, musisz użyć allow-discrete trybu zachowania przejścia.

Właściwość transition-behavior

Tryb allow-discrete umożliwia przejścia dyskretne i jest wartością właściwości transition-behavior. transition-behavior może przyjmować 2 wartości: normalallow-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: ten pokaz przejścia zawiera inną technikę niż pierwszy pokaz animacji, ale wizualnie wygląda podobnie.

Skrót transition również ustawia tę wartość, więc możesz pominąć tę właściwość i zamiast tego użyć słowa kluczowego allow-discrete na końcu skrótu transition dla każdego przejścia.

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

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

Jeśli animujesz kilka oddzielnych właściwości, musisz dodać allow-discrete po każdej z nich. 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 wejścia

Do tej pory omawialiśmy animacje wyjścia, ale aby utworzyć animacje wejścia, musisz użyć reguły @starting-style.

Użyj @starting-style, aby zastosować styl, który przeglądarka może sprawdzić, zanim element zostanie otwarty na stronie. To stan „przed otwarciem” (gdzie zaczyna się animacja).

/*  0. 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;
}

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

/*  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 stan wejścia i wyjścia dla tych elementów listy TODO:

Animowanie elementów do i z poziomu najwyższej warstwy

Aby animować elementy do i z warstwy najwyższej, określ @starting-style w stanie „otwarte”, aby poinformować przeglądarkę, skąd ma się rozpocząć animacja. W przypadku okna stan otwarty jest definiowany za pomocą atrybutu [open]. W przypadku wyskakującego okienka użyj pseudoklasy :popover-open.

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

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

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

/*   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 są różne. Aby ją uruchomić, animuj obszar od dołu widocznego obszaru, zamknij efekt u góry tego obszaru. Jest on też napisany za pomocą zagnieżdżonego kodu CSS, co zapewnia lepszą wizualizację.

Podczas animowania wyskakującego okienka użyj pseudoklasy :popover-open zamiast atrybutu open używanego wcześniej.

.settings-popover {
  &:popover-open {
    /*  0. IS-OPEN STATE  */
    /*  state when popover is open, BOTH:
        what we're transitioning *in* to 
        and transitioning *out* from */
    transform: translateY(0);
    opacity: 1;

    /*  1. 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;
    }
  }
  
  /*  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

Aby zanikać popover lub dialog z górnej warstwy, dodaj do listy przejść właściwość overlay. popover i dialog uciekają z klipów i przekształceń przodków, a także umieszczają zawartość w górnej warstwie. Jeśli nie wybierzesz opcji overlay, element natychmiast wróci do stanu ucięcia, przekształcenia i przykrycia, a Ty nie zobaczysz przejścia.

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

Zamiast tego dodaj overlay do przejścia lub animacji, aby animować overlay wraz z resztą funkcji, i upewnij się, że pozostaje on na najwyższej warstwie podczas animacji. Dzięki temu będzie wyglądać znacznie płynniej.

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

Dodatkowo, gdy masz otwarte na warstwie górnej wiele elementów, nakładka pomaga kontrolować płynne przejście do warstwy górnej i z niej. Różnicę możesz zobaczyć na tym prostym przykładzie. Jeśli nie zastosujesz overlay do drugiego wyskakującego okienka podczas przechodzenia do niego, najpierw wyjdzie ono z poziomu najwyższego, przeskakując za inne wyskakujące okienko, a dopiero potem rozpocznie się przejście. Nie jest to zbyt płynny efekt.

Uwaga dotycząca przejść między widokami

Jeśli wprowadzasz zmiany w DOM, np. dodajesz i usuwasz elementy z DOM, innym świetnym rozwiązaniem na płynne animacje są przejścia między widokami. Oto 2 przykłady z powyżej, które zostały utworzone za pomocą przejść między widokami.

W tym pierwszym pokazie zamiast konfigurowania @starting-style i innych przekształceń CSS przejścia będą obsługiwane przez przejścia widoku. Przejście między widokami jest konfigurowane w ten sposób:

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

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

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

/* etc. */

Następnie w JavaScript owiń mutację DOM (w tym przypadku usuwanie karty) w ramy przejścia 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 dostosować zanikanie i zmienianie wyglądu każdej karty do nowego położenia.

Innym przykładem, w którym może to być przydatne, jest dodawanie i usuwanie elementów listy. W takim przypadku musisz pamiętać, aby dodać unikalny identyfikator view-transition-name do każdej utworzonej karty.

Podsumowanie

Te nowe funkcje platformy przybliżają nas do płynnych animacji otwierania i zamykania na platformie internetowej. Aby dowiedzieć się więcej, kliknij te linki: