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
icontent-visibility
na osi czasu klatki kluczowej (od Chrome 116). - Właściwość
transition-behavior
z kluczowym słowemallow-discrete
, aby umożliwić przejścia z osobnych właściwości, takich jakdisplay
(z Chrome 117). - Reguła
@starting-style
służąca do animowania efektów wejścia z poziomudisplay: 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 display
i content-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: none
i opacity: 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: 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;
}
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: