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 ausblendbare 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 diesen 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 Eintrittseffekten von display: none in die oberste Ebene (ab 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 zum Zeitpunkt des Frames ausgetauscht. 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 über einen Zeitraum von 0,5 Sekunden auf 0 animiert und dann auf „none“ (nicht anzeigen) 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.

Dies ist ein einfaches Beispiel, das zeigt, was Sie mit einem Übergang tun können (siehe Demo im Abschnitt „Übergang“). Mit Übergängen lassen sich jedoch keine komplexeren Animationen erstellen, wie im folgenden Beispiel:

.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 sollten Sie den DOM-Knoten mit einem Zeitlimit entfernen, damit die Animation zuerst abgeschlossen werden kann.

Übergang zwischen einzelnen Animationen

Im Gegensatz zur Animation diskreter Properties mit keyframes müssen Sie für den Übergang diskreter Properties den allow-discrete-Modus für das Übergangsverhalten 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. Beginnen Sie die Animation am unteren Rand des Darstellungsbereichs und beenden Sie sie oben im Darstellungsbereich. Außerdem wurde es mit verschachteltem CSS geschrieben, um eine bessere visuelle Kapselung zu ermöglichen.

Verwenden Sie beim Animieren eines Pop-ups die Pseudoklasse :popover-open anstelle des bisher verwendeten Attributs 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 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. Wenn Sie overlay nicht festlegen, wird Ihr Element sofort wieder zugeschnitten, transformiert und verdeckt. Der Übergang wird nicht 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 mithilfe des Overlays einen reibungslosen Übergang zwischen der obersten Ebene und den darunter liegenden Ebenen steuern. In diesem einfachen Beispiel sehen Sie den Unterschied. 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 nicht sehr flüssig.

Hinweis zu Ansichtsübergängen

Wenn Sie DOM-Änderungen vornehmen, z. B. Elemente zum DOM hinzufügen oder daraus entfernen, sind Blickwechsel eine weitere gute Lösung für flüssige Animationen. Hier sind zwei der oben genannten Beispiele, die mit Ansichtsübergängen erstellt wurden.

In dieser ersten Demo werden anstelle von @starting-style und anderen CSS-Transformationen Ansichtsübergänge verwendet. 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 Ausblenden 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

Mit diesen neuen Plattformfunktionen sind wir einem reibungslosen Wechsel zwischen den Ansichten auf der Webplattform einen Schritt nähergekommen. Weitere Informationen finden Sie unter folgenden Links: