Bewegung ist ein wesentlicher Bestandteil jeder digitalen Umgebung, der Nutzer von einer Interaktion zur nächsten führt. Die Animationen auf der Webplattform sind jedoch nicht immer flüssig. Dazu gehören die Möglichkeit, Ein- und Ausblendungsanimationen ganz einfach zu erstellen und für minimierbare Elemente wie Dialogfelder und Pop-ups eine flüssige Animation zur und von der obersten Ebene zu ermöglichen.
Um diese Lücken zu schließen, enthalten Chrome 116 und 117 vier neue Webplattformfunktionen, die flüssige Animationen und Übergänge für einzelne Properties ermöglichen.
Zu den vier neuen Funktionen gehören:
- Möglichkeit,
display
undcontent-visibility
auf einer Keyframe-Zeitachse zu animieren (ab Chrome 116) - Die Property
transition-behavior
mit dem Keywordallow-discrete
, um Übergänge zwischen diskreten Properties wiedisplay
zu ermöglichen (ab Chrome 117). - Die
@starting-style
-Regel zum Animieren von Effekten für Einträge ausdisplay: none
in die oberste Ebene (aus Chrome 117). - Mit dem Attribut
overlay
lässt sich das Verhalten der obersten Ebene während einer Animation steuern (ab Chrome 117).
Animationen in Keyframes anzeigen
Ab Chrome 116 können Sie display
und content-visibility
in Keyframe-Regeln verwenden. Diese werden dann ausgetauscht, wenn der Keyframe auftritt. Dafür sind keine zusätzlichen neuen Werte erforderlich:
.card {
animation: fade-out 0.5s forwards;
}
@keyframes fade-out {
100% {
opacity: 0;
display: none;
}
}
Im vorherigen Beispiel wird die Deckkraft innerhalb von 0,5 Sekunden auf „0“ gesetzt und dann auf „none“ gesetzt. Außerdem sorgt das Schlüsselwort forwards
dafür, dass die Animation im Endzustand bleibt, sodass das Element, auf das sie angewendet wird, display: none
und opacity: 0
bleibt.
In diesem einfachen Beispiel werden die Möglichkeiten von Übergangspunkten nachgeahmt (siehe Demo im Abschnitt Übergang). Komplexere Animationen wie im folgenden Beispiel können mit Übergängen jedoch nicht erstellt werden:
.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;
}
}
Die spin-and-delete
-Animation ist eine Ausblendungsanimation. Zuerst dreht sich die Karte um die Y-Achse, durchläuft eine Farbtonrotation und ändert dann bei 80%
in der Zeitleiste ihre Deckkraft von 1 auf 0. Schließlich wird die Karte von display: block
zu display: none
geändert.
Anstatt diese Ausstiegsanimationen direkt auf ein Element anzuwenden, können Sie einen Trigger für die Animationen einrichten. Beispiel: Sie binden einen Event-Listener an eine Schaltfläche an, die eine Klasse auslöst, um die Animation anzuwenden.
.spin-out {
animation: spin-and-delete 1s ease-in forwards;
}
document.querySelector('.delete-btn').addEventListener('click', () => {
document.querySelector('.card').classList.add('spin-out');
})
Das Beispiel oben hat jetzt den Endstatus display:none
. In vielen Fällen empfiehlt es sich, den DOM-Knoten mit einem Zeitlimit zu entfernen, damit die Animation zuerst beendet werden kann.
Übergang zwischen einzelnen Animationen
Anders als bei der Animation diskreter Eigenschaften mit Keyframes müssen Sie für den Übergang von diskreten Eigenschaften den Übergangsmodus allow-discrete
verwenden.
Das transition-behavior
-Attribut
Der Modus allow-discrete
ermöglicht diskrete Übergänge und ist ein Wert der Property transition-behavior
. transition-behavior
kann zwei Werte haben: normal
und 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;
}
Dieser Wert wird auch durch die Kurzschreibweise transition
festgelegt. Sie können die Property also weglassen und stattdessen für jeden Übergang das Keyword allow-discrete
am Ende der Kurzschreibweise transition
verwenden.
.card {
transition: opacity 0.5s, display 0.5s allow-discrete;
}
.card.fade-out {
opacity: 0;
display: none;
}
Wenn Sie mehrere einzelne Properties animieren, müssen Sie nach jeder Property, die Sie animieren möchten, allow-discrete
einfügen. Beispiel:
.card {
transition: opacity 0.5s, display 0.5s allow-discrete, overlay 0.5s allow-discrete;
}
.card.fade-out {
opacity: 0;
display: none;
}
Die @starting-style
-Regel für Einstiegsanimationen
Bisher ging es in diesem Artikel um Ausstiegsanimationen. Wenn Sie Eintrittsanimationen erstellen möchten, müssen Sie die Regel @starting-style
verwenden.
Mit @starting-style
können Sie einen Stil anwenden, den der Browser abrufen kann, bevor das Element auf der Seite geöffnet wird. Dies ist der Status „Vor dem Öffnen“, von dem aus die Animation beginnt.
/* 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);
}
Jetzt haben Sie sowohl einen Eintritts- als auch einen Austrittsstatus für diese TODO-Listenelemente:
Elemente von und zur obersten Ebene animieren
Wenn Sie Elemente von und zur obersten Ebene animieren möchten, geben Sie die @starting-style
im Status „offen“ an, um dem Browser mitzuteilen, von wo aus die Animation beginnen soll. Für ein Dialogfeld wird der geöffnete Status mit dem Attribut [open]
definiert. Verwenden Sie für ein Pop-over die Pseudoklasse :popover-open
.
Ein einfaches Beispiel für einen Dialog könnte so aussehen:
/* 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;
}
Im nächsten Beispiel sind die Ein- und Ausblendeffekte unterschiedlich. Animieren Sie dazu vom unteren Rand des Darstellungsbereichs nach oben und beenden Sie den Effekt oben im Darstellungsbereich. Er ist außerdem mit verschachteltem CSS geschrieben, um eine bessere visuelle Kapselung zu ermöglichen.
Verwenden Sie bei der Animation eines Pop-overs die Pseudoklasse :popover-open
anstelle des zuvor verwendeten open
-Attributs.
.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
Unterkunft
Wenn Sie ein popover
oder dialog
in der obersten Ebene ausblenden möchten, fügen Sie der Liste der Übergänge die Property overlay
hinzu. Mit popover
und dialog
werden übergeordnete Clips und Transformationen ausgebrochen und die Inhalte in die oberste Ebene verschoben. Ohne Übergang von overlay
wird das Element sofort wieder zugeschnitten, umgewandelt und verdeckt und der Übergang wird nicht mehr angezeigt.
[open] {
transition: opacity 1s, display 1s allow-discrete;
}
Fügen Sie overlay
stattdessen in den Übergang oder die Animation ein, um overlay
zusammen mit den restlichen Elementen zu animieren und dafür zu sorgen, dass es sich bei der Animation in der obersten Ebene befindet. Das sieht viel flüssiger aus.
[open] {
transition: opacity 1s, display 1s allow-discrete, overlay 1s allow-discrete;
}
Wenn Sie mehrere Elemente in der obersten Ebene geöffnet haben, können Sie mit dem Overlay außerdem den reibungslosen Übergang in und aus der obersten Ebene steuern. Den Unterschied sehen Sie in diesem einfachen Beispiel. Wenn Sie overlay
beim Ausblenden des zweiten Pop-ups nicht anwenden, wird es zuerst aus der obersten Ebene verschoben und springt hinter das andere Pop-up, bevor der Übergang beginnt. Das ist kein sehr flüssiger Effekt.
Hinweis zu Ansichtsübergängen
Wenn Sie DOM-Änderungen vornehmen und z. B. Elemente zum DOM hinzufügen oder daraus entfernen, können Sie auch Ansichtsübergänge reibungslos gestalten. Hier sind zwei der oben genannten Beispiele, die mit Ansichtsübergängen erstellt wurden.
In dieser ersten Demo werden @starting-style
- und andere CSS-Transformationen nicht eingerichtet, sondern der Übergang wird von Ansichtsübergängen übernommen. Die Ansichtsübergänge werden so eingerichtet:
Geben Sie zuerst in CSS jeder Karte eine individuelle view-transition-name
.
.card-1 {
view-transition-name: card-1;
}
.card-2 {
view-transition-name: card-2;
}
/* etc. */
Anschließend verpacken Sie die DOM-Mutation (in diesem Fall das Entfernen der Karte) in JavaScript in einen Ansichtsübergang.
deleteBtn.addEventListener('click', () => {
// Check for browser support
if (document.startViewTransition) {
document.startViewTransition(() => {
// DOM mutation
card.remove();
});
}
// Alternative if no browser support
else {
card.remove();
}
})
Jetzt kann der Browser das Aus- und Morphen jeder Karte an ihre neue Position verarbeiten.
Ein weiteres Beispiel, in dem dies praktisch sein kann, ist die Demo zum Hinzufügen und Entfernen von Listenelementen. In diesem Fall müssen Sie für jede erstellte Karte eine eindeutige view-transition-name
hinzufügen.
Fazit
Diese neuen Plattformfunktionen bringen uns den reibungslosen Einstiegs- und Exit-Animationen auf der Webplattform einen Schritt näher. Weitere Informationen finden Sie unter den folgenden Links: