Vier neue CSS-Funktionen für flüssige Einstiegs- und Exit-Animationen

Bewegung ist ein zentraler Bestandteil jeder digitalen Erfahrung und leitet die Nutzenden von einer Interaktion zur nächsten. Es gibt jedoch einige Lücken bei den flüssigen Animationen auf der Webplattform. Dazu gehört die Möglichkeit, Eingangs- und Exit-Animationen einfach zu animieren sowie gleitende Animationen zum und vom obersten Layer für schließbare Elemente wie Dialogfelder und Pop-overs zu ermöglichen.

Um diese Lücken zu schließen, enthält Chrome 116 und 117 vier neue Webplattformfunktionen, die reibungslose Animationen und Übergänge für diskrete Properties ermöglichen.

Zu diesen vier neuen Funktionen gehören:

  • display und content-visibility können auf einer Keyframe-Zeitachse animiert werden (ab Chrome 116).
  • Die Eigenschaft transition-behavior mit dem Schlüsselwort allow-discrete, um Übergänge von einzelnen Eigenschaften wie display zu ermöglichen (aus Chrome 117).
  • Die @starting-style-Regel zum Animieren von Effekten von Einträgen aus display: none in die oberste Ebene (aus Chrome 117).
  • Die Eigenschaft overlay zur Steuerung des Verhaltens der obersten Ebene während einer Animation (aus 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 animiert und dann auf „none“ gesetzt. Außerdem sorgt das Schlüsselwort forwards dafür, dass die Animation in ihrem Endzustand verbleibt, 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 Exit-Animation. Zuerst dreht sich die Karte um die Y-Achse, durchläuft eine Farbtonrotation und wechselt dann bei 80% durch die Zeitachse die Deckkraft von 1 auf 0. Zuletzt wechselt die Karte von display: block zu display: none.

Anstatt sie direkt auf ein Element anzuwenden, können Sie für diese Exit-Animationen einen Trigger einrichten. So können Sie beispielsweise einen Event-Listener an eine Schaltfläche anhängen, die eine Klasse zum Anwenden der Animation auslöst:

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

Im obigen Beispiel ist jetzt der Endzustand display:none. In vielen Fällen empfiehlt es sich, den DOM-Knoten mit einem Zeitlimit zu entfernen, damit die Animation zuerst beendet werden kann.

Diskrete Animationen übergehen

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 Attribut transition-behavior

Der Modus allow-discrete ermöglicht diskrete Übergänge und ist ein Wert der Eigenschaft transition-behavior. transition-behavior akzeptiert zwei Werte: 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;
}
Hinweis: Diese Übergangsdemo zeigt eine andere Technik als die erste Animationsdemo, sieht aber ähnlich aus.

Die Abkürzung transition legt diesen Wert ebenfalls fest, sodass Sie die Eigenschaft weglassen können und stattdessen das Schlüsselwort allow-discrete am Ende der Abkürzung transition für jeden Übergang verwenden.

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

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

Wenn Sie mehrere einzelne Eigenschaften animieren, müssen Sie nach jeder Eigenschaft, 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 Eintragsanimationen

Bisher wurden in diesem Artikel Exit-Animationen behandelt. Um Zugangsanimationen zu erstellen, müssen Sie die Regel @starting-style verwenden.

Verwenden Sie @starting-style, um einen Stil anzuwenden, den der Browser aufrufen kann, bevor das Element auf der Seite geöffnet ist. Dies ist der Status „Vor dem Öffnen“ (von dem aus die Animation gestartet wird).

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

Jetzt haben Sie sowohl einen Ein- als auch einen Ausstiegsstatus für diese ToDo-Listenelemente:

Elemente zur und aus der obersten Ebene animieren

Um Elemente von der obersten Ebene in die und von der obersten Ebene zu animieren, geben Sie im Status "open" das @starting-style-Symbol an, um dem Browser mitzuteilen, von wo aus die Animation gestartet werden soll. Bei einem Dialogfeld wird der geöffnete Zustand mit dem Attribut [open] definiert. Verwenden Sie für ein Pop-over die Pseudoklasse :popover-open.

Ein einfaches Beispiel für ein Dialogfeld könnte so aussehen:

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

Im nächsten Beispiel unterscheiden sich die Ein- und Ausstiegseffekte. 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. 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 Unterkunft

Zum Ausblenden eines popover- oder dialog-Elements aus der obersten Ebene fügen Sie zum Schluss die Eigenschaft overlay zur Liste der Übergänge hinzu. popover und dialog maskieren Ancestor-Clips und -Transformationen und platzieren den Inhalt außerdem im obersten Layer. Wenn Sie overlay nicht übergehen, 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üge stattdessen overlay in den Übergang oder die Animation ein, um overlay zusammen mit den übrigen Elementen zu animieren. Achte darauf, dass es bei der Animation auf der obersten Ebene verbleibt. 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 zur obersten Ebene steuern. Den Unterschied sehen Sie in diesem einfachen Beispiel. Wenn Sie overlay beim Übergang nicht auf das zweite Pop-over anwenden, wird es zuerst aus der obersten Ebene verschoben und hinter das andere Pop-over gesprungen, bevor der Übergang gestartet wird. Dieser Effekt ist nicht sehr gleichmäßig.

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 obigen 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. Der Ansichtsübergang wird so eingerichtet:

Weisen Sie zuerst im CSS jeder Karte eine einzelne view-transition-name zu.

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

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

/* etc. */

Fassen Sie dann in JavaScript die DOM-Mutation (in diesem Fall das Entfernen der Karte) in einen Ansichtsübergang ein.

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 für diese Funktion ist die Demo zum Hinzufügen/Entfernen von Listenelementen. In diesem Fall musst du jeder erstellten 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: