Sie sind unsere täglichen Begleiter und nicht mehr wegzudenken. Die Rede ist natürlich von unseren Smartphones. Mehrere Stunden täglich verbringen wir vor den kleinen Bildschirmen und nutzen eifrig das ständig wachsende Angebot an Apps aus Stores oder dem Web. Doch jetzt mal Hand aufs Herz. Könnten Sie beim Blick auf eine App noch unterscheiden, ob es sich um eine native oder eine hybride App handelt? Wohl kaum.

In der Vergangenheit hinkten Webapplikationen nativ entwickelten Apps immer einen Schritt hinterher. Warum? Viele nativ nutzbare Funktionen wie beispielsweise der Zugriff auf das Filesystem oder das Erhalten von Push-Notifications waren als Schnittstelle im Browser schlichtweg nicht vorhanden.

Doch die Bemühungen der Browserhersteller, diese Lücken im Zuge des Projekts „FUGU“ zu schließen, haben Früchte getragen. Mit einem erstaunlichen Tempo wurden in den letzten Jahren viele Features in den Browsern implementiert und machten Webapplikationen den Weg frei für nun völlig neue Möglichkeiten. Tools wie Capacitor tun ihr übriges und bringen Webapplikationen, “verpackt” als installierbar für die jeweilige Plattform, in die App-Stores dieser Welt.

Container-Transforms, das Haar in der Suppe

Doch so gut auch die Lücken in der Vergangenheit geschlossen werden konnten, gab es hinsichtlich der UX immer einen großen Punkt, in dem sich Webapplikationen und native Apps voneinander unterscheiden ließen. Und zwar bei Animationen. Klar, Übergänge zwischen Views können auch innerhalb von Webapplikationen hübsch animiert und gestaltet werden. Doch Übergänge mit Hilfe von sogenannten  “Container-Transforms” waren bisher undenkbar bzw. nur mit viel Aufwand umzusetzen.

 

Quelle: material.io

Und warum? Im Web sind wir nun mal an das DOM und dessen Struktur gebunden. Natürlich können wir Elemente mit “position: absolute“ aus dieser Struktur herauslösen und wie Kaugummi in Größe und Form verändern. Das funktioniert hervorragend, solange wir innerhalb einer View bleiben und nicht zwischen Views wechseln, also routen. Denn in unseren Single-Page-Applications werden beim Routen die bestehenden Views zerstört und die Neuen anschließend erzeugt. Um also beim Routen auch Container-Transforms anbieten zu können, müssten wir quasi beide Zustände gleichzeitig in einer Art Übergangszustand zur Verfügung haben.

Natürlich können die etablierten Frameworks auch Routing-Animationen abdecken. Beim Angular-Framework war dies beispielsweise in der Vergangenheit schon mit dem eigens mitgelieferten @angular/animationsPackage möglich. Doch gibt es nach dieser Hürde noch viele weitere, wie z.B. korrektes Stacking- und Überblendungs-Handling.

Die nativen Entwickler haben es hier deutlich einfacher. Für solche Fälle stehen eigens dafür erdachte APIs zur Verfügung, die die Gestaltung erheblich vereinfachen. Doch auch wir Webentwickler können endlich aufatmen. Die View-Transition-API ereilt uns als Retter in der Not.

Die View-Transition-API als Retter in der Not

Mit ihrer Hilfe können auch wir Webentwickler – ohne die Notwendigkeit von zusätzlichen Frameworks, Libraries oder gar aufwendigen JavaScript – nur mit reinem CSS bildhübsche Animationen gestalten. Leider gibt es allerdings noch einen kleinen Wermutstropfen zu verschmerzen, bevor wir einsteigen.

Abbildung: Die View-Transition-API als Retter in der Not

Die API steht uns in Chrome schon einige Zeit zur Verfügung, und auch Safari hat jüngst (mit Version 18) endlich nachgezogen. Nur Firefox lässt noch etwas auf sich warten und ist das fehlende Glied zur Vollendung der Baseline-Compatibility. Doch wenn man den Gerüchten Glauben schenken darf, sollte Firefox auch Ende Q1/Q2 2025 mit den anderen Platzhirschen gleichziehen.

Das soll Sie aber nicht daran hindern, sich mit der API schon einmal vertraut zu machen und sie bereits in Ihren Projekten einzusetzen. Also los geht’s!

Nur eine Zeile JavaScript ist nötig

Um eine View-Transition anzustoßen, bedarf es lediglich einer Zeile JavaScript. Auf dem “document”-Objekt steht uns die Methode “startViewTransition” zur Verfügung, die eine Callback-Funktion entgegennimmt.

Wozu diese Callback-Funktion genau benötigt wird, erfahren wir gleich. Werfen wir zuerst einmal einen Blick darauf, was der Browser bei einer View-Transition eigentlich tut.

Abbildung: Was der Browser bei einer View-Transition tut

Nachdem wir mit “startViewTransition” den Vorgang angestoßen haben, macht der Browser zunächst einen “Snapshot” der gesamten sichtbaren View (richtig gelesen, dabei handelt es sich tatsächlich um ein Bild).

Anschließend werden im DOM die Changes durchgeführt, die zum “Nachher-Zustand” führen. Hierbei kommt auch schon die eingangs erwähnte Callback-Funktion ins Spiel. In diesem Callback führen wir nämlich diese besagten DOM-Changes durch.

Was kann das sein? Im Grunde alle Arten von Änderungen, die zu dem Zustand führen, zu dem wir animieren wollen. Also beispielsweise routen, Elemente zum DOM hinzufügen, entfernen oder modifizieren.

Sind die Changes durchgeführt, wird vom Browser ein weiterer Snapshot bzw. eine  “Live-View” des neuen Zustandes erstellt.

Crossfade als Default-Transition

Nun haben wir also einen Vorher- und Nachher-Zustand. Als Default-Animation führt der Browser nun einen “Crossfade” (also eine Überblendung mittels Deckkraftreduzierung) dieser beiden Bilder durch. Die View-Transition ist vollendet.

–Stackblitz

Es sei noch erwähnt, dass der Nutzer die DOM-Changes erst mitbekommt, nachdem sie durchgeführt und die Snapshots erstellt wurden. Das passiert allerdings so schnell, dass hierbei keinerlei “Freezes” oder “Delays” zu befürchten sind (es sei denn, man betreibt ausschweifende Berechnungen innerhalb der Callback-Funktion).

Nachdem wir nun verstanden haben, was hinter den Kulissen abläuft, bleibt noch zu klären, wie der Browser diese Transition im DOM eigentlich umsetzt. Damit die View-Transitions per CSS animiert werden können, müssen diese irgendwo im DOM zu finden sein. Der Browser erstellt dazu für die View-Transition und die dazugehörigen Bildpaare eigene Pseudo-DOM-Elemente.

Abbildung: Der Browser erstellt dazu für die View-Transition und die dazugehörigen Bildpaare eigene Pseudo-DOM-Elemente

Diese Elemente sitzen direkt unter der „Document-Root“, also direkt unterhalb des <html>-Tags. Dadurch befinden sie sich über allen anderen Elementen, was das Problem möglicher überlagernder Elemente von vornherein eliminiert.

Pseudoelemente im DOM ermöglichen Stylebarkeit

Das “::view-transition”-Element dient als Overlay-Root-Element und ist der Ausgangspunkt aller weiteren View-Transition-Elemente. Die “::view-transition-group” ist ein zusätzliches Gruppierungselement und das Root-Element einer einzelnen Transition und beinhaltet das “::view-transition-image-pair”-Element, was die beiden “Snapshots” bzw. die Vorher- und Nachher-Views beinhaltet. “::view-transition-old” und “-new” sind dann die eigentlichen Vorher-Nachher-Elemente und können über diese Selektoren per CSS direkt angesprochen und mit CSS Animationen versehen werden.

Am besten schauen Sie sich die Elemente einmal selbst im Browser an und sind etwas kreativ. Was Sie allerdings beachten müssen, ist, dass die Elemente nur existieren, während die View-Transition läuft. Das heißt, für eine genauere Inspektion und Debugging sollten Sie die Browser-internen Animation-Dev-Tools zur Hilfe nehmen.

Exkurs: Der Animation-Drawer für einfaches Debugging

Öffnen wir in Chrome die Entwicklerkonsole und drücken “Strg+Shift+P,” öffnet sich – ähnlich wie in VS Code – ein Command-Panel. Hier können wir nach “animation” filtern und uns mit “Show Animations” den Animation-Drawer anzeigen lassen.

Abbildung: Der Animation-Drawer für einfaches Debugging

Mit den Prozent-Toggle-Buttons können wir dann ganz einfach die Animationsgeschwindigkeit verlangsamen. Wer noch mehr Kontrolle möchte, muss zunächst auf den “Pause-Button” drücken und im Anschluss die Animation triggern. Als Ergebnis erhalten wir einen “Frame-Identifyer”, inklusive einer kompletten Animations-Timeline. Diese bietet uns eine Übersicht über alle beteiligten Teilanimationen.

Abbildung: Animations-Timeline

So können wir sehr granular jederzeit “vor- und zurückspulen” und eine sehr detailgenaue Animation erstellen.

Auch einzelne View-Elemente können separat animiert werden

Nun haben wir es geschafft, eine Transition der kompletten View vorzunehmen. Das sieht zwar schon ganz schick aus, ist aber nicht das, was wir wollen, wenn wir an ausschweifende Animationen denken. Bei diesen besteht eine Animation meist aus mehreren frei beweglichen Elementen und nicht nur aus einer statischen View. Aber auch das ist mit der View-Transition-API möglich.

Abbildung: View-Elemente können separat animiert werden

Wir können nämlich einzelne Elemente gezielt “ausschneiden” und separat animieren. In diesem Beispiel ist es das “Header-Element”. Für dieses zusätzliche Element legt der Browser separate Image-Paare an, die wir wieder als Pseudoelemente im DOM vorfinden und so separat animieren können.

Abbildung: Pseudoelemente im DOM

Wir sehen auch direkt, dass pro Element eigene “::view-transition-groups” erstellt werden. Um dem Browser mitzuteilen, dass ein Element separat erfasst werden soll, reicht es aus, auf diesem per CSS die Property “view-transition-name” zu setzen.

Zu beachten ist, dass der Name hier frei wählbar ist und nicht in Anführungszeichen gepackt werden muss. Soll ein Image-Paar erstellt werden, müssten Sie sowohl in der Vorher- als auch der Nachher-View die entsprechenden Elemente mit dem gleichen Namen versehen. So weiß der Browser, welche Bildpaare zusammengehören. Wird nur ein Element referenziert, wird auch nur ein Bildelement angelegt.

Achtung: Jedes Namenspaar darf innerhalb einer Transition genau einmal existieren. Ansonsten spuckt Ihnen der Browser in der Konsole eine Fehlermeldung aus, und die Transition ist nicht ausführbar.

Verändern Sie beispielsweise die Position des “Nachher-Elements”, bemerkt das der Browser und beschenkt Sie automatisch mit einer Transition, die schon von Grund auf etwas hermacht.

Warum die “Live-View” wichtig ist

In den vorherigen Abschnitten habe ich immer mal wieder erwähnt, dass der Browser für den “Nachher-Zustand” keinen Snapshot, sondern ein Live-View-Element anlegt. Doch wozu soll das gut sein?

Nun ja, in den bisherigen Beispielen haben wir immer nur Elemente mit der View-Transition-API animiert, die sich selbst nicht bewegen. Die Rede ist hier beispielsweise von Video-Playern oder Elementen, die GIFs beinhalten.

Wenn für solche Elemente lediglich “Snapshots” angelegt werden, würde das Video oder das GIF für die Zeit der Animation einfrieren und erst im Anschluss – evtl. zu einem ganz anderen Timestamp – wieder weiterlaufen. Das sähe sehr unschön aus. Ein tolles Beispiel dafür ist in der originalen View-Transition-API Demo zu sehen.

Die Dame in der zweiten Card bewegt sich rhythmisch zur Musik, die sie hört. Wenn wir nun auf die Card klicken, erfolgt eine Transition zur entsprechenden Playlist-Ansicht. Aber wohlgemerkt, ohne jegliche Unterbrechung der Tanzdarbietung, dank der Live-View. Wer sich das alles noch einmal genauer anschauen möchte (die Animation ist zugegeben etwas schnell), kann sich gerne wieder mit dem Animation-Drawer behelfen.

Default-Animationen aus dem Browser-Stylesheet

Die bisher gezeigten Transitions machen doch schon etwas her, oder? Und das ganz ohne, dass wir auch nur eine Zeile CSS-Animation-Code geschrieben haben. Wie das geht? Mit Hilfe des Browser-Stylesheets. Jeder Browser wird bereits mit Default-Styles für HTML-Elemente ausgeliefert. In diesem Stylesheet sind natürlich auch schon Default-Animationen für die View-Transition-API aufgeführt.

Abbildung: Auszug aus dem Chrome-Stylesheet

Auszug aus dem Chrome-Stylesheet

Hier sehen wir einen Auszug aus dem Stylesheet des Chrome Browsers. Hinter den Animationen “-ua-view-transition-fade-out” und “-ua-view-transition-fade-in” verbergen sich bspw. die Effekte für den eingangs gezeigten Crossfade-Effekt. Diese Effekte können wir für unsere Zwecke mitnutzen oder auch komplett überschreiben.

Nicht nur Single-Page-Applications profitieren

Bisher haben wir die View-Transition-API nur im Kontext von Single-Page-Applications verwendet. Aber wie sieht es z.B. im Multi-Page-Kontext aus?

Auch hier müssen wir nicht auf die View-Transition-API verzichten. Allerdings sieht der Support nicht nur bei Firefox, sondern auch bei Safari etwas dürftig aus und funktioniert aktuell nur in Chromium-basierten Browsern.

In diesem Falle lassen sich View-Transitions sogar noch einfacher nutzen. Wir müssen dazu nämlich nicht mal mehr eine Zeile JavaScript verwenden. Im Multi-Page-Kontext finden Page-Transitions im üblichen Fall durch das Klicken auf einen Link statt. Damit nun aber nicht plötzlich ALLE Multi-Kontext-Pages dieser Welt View-Transitions aktiviert haben, sind sie “opt-in”. Heißt, wir müssen sie bewusst aktivieren, um sie zu verwenden.

Zur Aktivierung müssen beide Seiten die “@view-transition”-CSS-Regel mit “navigation: auto” implementieren.

Wichtig zu erwähnen ist außerdem noch, dass die Multi-Page-View-Transitions nur innerhalb einer Origin zulässig sind bzw. nur dort ausgeführt werden. Wir können also bspw. von “www.meine-origin.de” zu “www.meine-origin/details” animieren. Aber nicht von “www.meine-origin.de” zu “www.google.com”.

Die View-Transition-API – Zusammenfassung

Ich hoffe, ich konnte Sie davon überzeugen, was für eine großartige Ergänzung die View-Transition-API für die Web- und die hybride Entwicklung darstellt. Aus ehemals aufwändigen Animationskonstruktionen werden im Handumdrehen einfach beherrschbare und bezaubernde Animationen. Und das nur mit der Hilfe von CSS (und im Falle der Single-Page-Apps mit einer Zeile JavaScript).

Durch die vom Browser erzeugten Pseudo-Elemente müssen wir uns um überlappende Elemente keine Sorgen machen und bekommen durch die Default-Styles des Browser-Stylesheets schon mit minimalstem Aufwand coole Effekte gezaubert.

Aber die hier gezeigten Beispiele kratzen nur an der Oberfläche. Ihrer Phantasie  sind keine Grenzen gesetzt. Deshalb kann ich Sie nur dazu ermutigen, selbst einmal Hand anzulegen und die View-Transition-API in Ihre Projekte einzubinden und dafür zu sorgen, dass sie nicht mehr von nativ entwickelten Apps zu unterscheiden sind.

Sascha Lehmann

Große Auswahl an günstigen Domain-Endungen – schon ab 0,08 € /Monat
Jetzt Domain-Check starten