Ruch jest podstawą każdego cyfrowego doświadczenia i pokazuje użytkownikowi, jak przejść z jednego elementu interakcji do następnego. Na platformie internetowej występują jednak pewne przerwy w płynnych animacjach. Do funkcji tych należy m.in. możliwość łatwego animowania animacji wejścia i wyjścia oraz płynnego animowania elementów, które można zamknąć, takich jak okna dialogowe i 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ższego poziomu (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 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 to umożliwić:
.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 brak. Dodatkowo słowo kluczowe forwards
sprawia, że animacja pozostaje w swoim końcowym stanie, 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 demonstrację w sekcji Przejścia). Przejścia nie umożliwiają jednak tworzenia bardziej złożonych animacji, takich jak ta:
.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 przechodzić przez całą gamę kolorów. Następnie w 80%
na osi czasu jej przezroczystość będzie się zmieniać od 1 do 0. Wreszcie karta zmienia się z display: block
na display: none
.
Zamiast stosować te animacje bezpośrednio do elementu, możesz skonfigurować dla nich odpowiednią regułę. Na przykład możesz dołączyć detektor zdarzeń do przycisku, który uruchamia klasę, aby zastosować animację. W tym celu:
.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 do oddzielnych usług
Właściwości, które animują się dyskretnie, nie powodują domyślnie zdarzeń przejścia. Aby to umożliwić, ustaw tryb zachowania podczas przejścia na allow-discrete
.
Właściwość transition-behavior
Właściwość transition-behavior
określa, czy w przypadku właściwości dyskretnych mają być uruchamiane przejścia. Może mieć 2 wartości: normal
i allow-discrete
, przy czym wartość początkowa to normal
.
normal
: Przenoszenie nie zostanie rozpoczęte w przypadku właściwości dyskretnych, tylko w przypadku właściwości umożliwiających interpolację.allow-discrete
: Przenoszenie rozpocznie się w przypadku właściwości dyskretnych i właściwości, w przypadku których można stosować interpolację.
Aby włączyć tryb allow-discrete
w przypadku konkretnej usługi, dodaj ją do skrótu transition
:
.card {
transition: opacity 0.25s, display 0.25s allow-discrete; /* Enable allow-discrete for the display property */
}
.card.fade-out {
opacity: 0;
display: none;
}
Podczas przenoszenia wielu oddzielnych właściwości musisz ustawić allow-discrete
dla każdej z nich. Na przykład:
.card {
transition: opacity 0.5s, display 0.5s allow-discrete, overlay 0.5s allow-discrete;
}
Aby zdefiniować zachowanie wszystkich właściwości w procesie przejścia, po deklaracji transition
należy zadeklarować transition-behavior: allow-discrete
. Jest to często najprostsze podejście.
.card {
transition: opacity 0.5s, display 0.5s, overlay 0.5s;
transition-behavior: allow-discrete; /* Note: be sure to write this after the shorthand */
}
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. Wprowadzanie: animacja od dołu widocznego obszaru w górę, a następnie odwrotnie. Jest ona też napisana za pomocą osadzonego CSS, co zapewnia lepszą wizualną izolację.
Podczas animowania wyskakującego okienka użyj pseudoklasy :popover-open
zamiast używanego wcześniej atrybutu open
.
.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 na koniec stonować element popover
lub dialog
z górnej warstwy, dodaj właściwość overlay
do listy przejść. 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 w 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 na temat przejścia 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 skonfigurowane 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 zająć się wygaszaniem i przekształceniem każdej karty w nowej pozycji.
Innym przykładem, w którym może się to przydać, 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: