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

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 und content-visibility auf einer Keyframe-Zeitachse zu animieren (ab Chrome 116)
  • Die Property transition-behavior mit dem Keyword allow-discrete, um Übergänge zwischen diskreten Properties wie display zu ermöglichen (ab Chrome 117).
  • Die @starting-style-Regel zum Animieren von Effekten für Einträge aus display: 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;
}
Hinweis: Diese Übergangsdemo zeigt eine andere Technik als die erste Animationsdemo, sieht aber optisch ähnlich aus.

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: