CSS · Browser APIs · Animationen · Navigation
CSS View Transitions API
seitenübergreifende Übergänge nativ im Browser

Die View Transitions API bringt das, was früher nur SPAs mit aufwendigen Frameworks erreichten, als native Browser-Funktion: nahtlose Animationen beim Seitenwechsel — mit view-transition-name für shared elements, CSS-Pseudoelementen für volle Stilkontrolle und Cross-Document-Unterstützung für Multi-Page-Apps.

15 Min. Lesezeit view-transition-name · ::view-transition · MPA · SPA · Navigation API Chrome 111+ · Chrome 126+ (MPA) · Firefox 136+

1. Was die View Transitions API löst

Seitenübergänge auf dem Web waren lange ein Kompromiss. SPAs mit React, Vue oder Angular konnten flüssige Animationen implementieren, weil sie die DOM-Kontrolle behalten — aber auf Kosten von Komplexität, Bundle-Größe und schlechter Performance beim initialen Laden. Klassische Multi-Page-Apps (MPAs) hatten jahrzehntelang nur den harten Seitenwechsel: weiß aufblitzen, neuer Inhalt erscheint. Die View Transitions API schließt diese Lücke mit einem eleganten Browser-nativen Mechanismus, der für beide Paradigmen funktioniert.

Das Kernkonzept ist verblüffend einfach: Der Browser macht einen Screenshot des aktuellen Zustands, führt die DOM-Änderung oder den Seitenwechsel durch, und animiert dann den Übergang zwischen altem Screenshot und neuem Zustand. Entwickler definieren via CSS, wie dieser Übergang aussehen soll — mit view-transition-name für Elemente, die "herübergezogen" werden sollen, und mit CSS-Pseudoelementen für Kontrolle über Timing und Easing. Die View Transitions API arbeitet dabei vollständig composited und blockiert nie den Main Thread während der Animation.

2. Grundprinzip: Snapshot → DOM-Änderung → Animation

Der Ablauf einer View Transition ist immer gleich, egal ob SPA oder MPA. Schritt 1: Der Browser friert das aktuelle Rendering ein und erstellt Snapshots für alle Elemente mit einem view-transition-name sowie einen Gesamt-Snapshot der Seite. Schritt 2: Die DOM-Änderung wird durchgeführt (für SPAs synchron, für MPAs durch das Laden der neuen Seite). Schritt 3: Der Browser erstellt neue Snapshots für die neue DOM-Situation. Schritt 4: Die Pseudo-Element-Bäume werden aufgebaut und die CSS-definierten Animationen starten.

Während der Animation existieren sowohl der alte als auch der neue DOM-Zustand als Snapshots gleichzeitig — als layered Pseudoelemente im ::view-transition-Baum. Die Snapshots werden als ::view-transition-old und ::view-transition-new Pseudoelemente repräsentiert. Der Browser zeigt diese Pseudoelemente übereinander an und animiert den Übergang. Das elegante daran: Für die Standardtransition (Cross-Fade) braucht man keine einzige Zeile CSS schreiben — der Browser liefert einen sauberen Überblende-Effekt out of the box.


/* The default view transition is a cross-fade — no CSS needed.
   Override or extend with custom styles: */

/* Control the root (full-page) transition */
::view-transition-old(root) {
  animation: 0.3s ease-in both fade-out;
}

::view-transition-new(root) {
  animation: 0.3s ease-out both fade-in;
}

@keyframes fade-out {
  from { opacity: 1; }
  to   { opacity: 0; }
}

@keyframes fade-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* Slide transition instead of cross-fade */
@keyframes slide-out-left {
  from { transform: translateX(0); }
  to   { transform: translateX(-100%); }
}

@keyframes slide-in-right {
  from { transform: translateX(100%); }
  to   { transform: translateX(0); }
}

::view-transition-old(root) {
  animation: 0.35s ease-in-out both slide-out-left;
}

::view-transition-new(root) {
  animation: 0.35s ease-in-out both slide-in-right;
}

3. ::view-transition-Pseudoelemente und CSS-Kontrolle

Die View Transitions API erstellt während einer Transition einen kompletten Baum aus Pseudoelementen über dem normalen Document-Rendering. Der Wurzel-Pseudoelement ist ::view-transition, der den gesamten Übergangszustand enthält. Darunter hängen ::view-transition-group([name])-Elemente für jeden benannten Transition-Teilnehmer. Jede Gruppe enthält ::view-transition-image-pair([name]), und darunter ::view-transition-old([name]) und ::view-transition-new([name]) als die eigentlichen Snapshot-Bilder.

Diese Pseudoelemente sind mit CSS vollständig steuerbar. Man kann jeden Teilnehmer unabhängig animieren, separate Timing-Funktionen setzen, oder auch einen Teilnehmer durch animation: none komplett aus der Transition herausnehmen. Ein wichtiger Aspekt: Der ::view-transition-group wird automatisch mit der Position und Größe des alten Elements initialisiert und animiert zur Position und Größe des neuen Elements — das ist der Mechanismus hinter den "fliegenden" Shared-Element-Animationen. CSS-Properties wie animation-timing-function, animation-duration und animation-delay können direkt auf den Pseudoelementen gesetzt werden.

4. view-transition-name: Shared Elements animieren

Das mächtigste Feature der View Transitions API sind Shared-Element-Animationen via view-transition-name. Wenn ein Element auf Seite A und ein Element auf Seite B denselben eindeutigen view-transition-name-Wert haben, animiert der Browser das Element nahtlos von seiner alten Position und Größe zu seiner neuen Position und Größe — ohne dass man Position, Größe oder Timing manuell berechnen muss. Der Browser liest diese Werte aus den Snapshots und berechnet eine FLIP-Animation (First, Last, Invert, Play) automatisch.

Kritische Einschränkung: Ein view-transition-name-Wert muss zu jedem Zeitpunkt eindeutig im Dokument sein. Zwei Elemente mit demselben Namen gleichzeitig im DOM führen dazu, dass die gesamte Transition abbricht. Das ist besonders relevant bei Listenelementen, die alle denselben Typ repräsentieren (z.B. Produktkarten): Hier muss der Name dynamisch generiert werden, z.B. mit einem ID-basierten Suffix wie view-transition-name: product-card-42. In HTML via style-Attribut, via CSS Custom Properties oder via JavaScript kann dieser Wert gesetzt werden.


/* Shared element: product image flies from list to detail page */

/* On product list page */
.product-card[data-id="42"] .product-image {
  view-transition-name: product-image-42;
  /* contain: layout; is automatically set for named elements */
}

.product-card[data-id="42"] .product-title {
  view-transition-name: product-title-42;
}

/* On product detail page — same names */
.product-detail .hero-image {
  view-transition-name: product-image-42;
}

.product-detail h1 {
  view-transition-name: product-title-42;
}

/* Customize the flight animation for the image */
::view-transition-group(product-image-42) {
  animation-timing-function: cubic-bezier(0.34, 1.56, 0.64, 1);
  animation-duration: 0.5s;
}

/* Fade the title separately with a slight delay */
::view-transition-old(product-title-42),
::view-transition-new(product-title-42) {
  animation-duration: 0.25s;
  animation-delay: 0.1s;
}

/* view-transition-name can also be set via inline style or JS:
   element.style.viewTransitionName = `product-image-${id}` */

5. SPA-Integration: document.startViewTransition()

Für Single-Page-Apps ist document.startViewTransition() die JavaScript-Einstiegsfunktion. Sie nimmt einen Callback, der die eigentliche DOM-Änderung durchführt. Der Browser sorgt dafür, dass vor dem Callback ein Snapshot des aktuellen Zustands erstellt wird, und nach dem Callback (wenn das zurückgegebene Promise resolved) den neuen Snapshot erstellt und die Transition startet. Der Callback kann asynchron sein — das ist wichtig für Datenabrufe, die vor dem DOM-Update abgewartet werden müssen.

Die startViewTransition()-Funktion gibt ein ViewTransition-Objekt zurück mit den Promises ready (Transition bereit), finished (Transition abgeschlossen) und updateCallbackDone (DOM-Update fertig). Über ready kann man z.B. Animationen mit der Web Animations API synchronisieren. Das finished-Promise ermöglicht Cleanup-Aktionen nach der Transition. Mit viewTransition.skipTransition() kann eine laufende Transition sofort abgebrochen werden — nützlich für schnelle Nutzer, die während einer Transition weiternavigieren.

6. MPA Cross-Document Transitions

Die ursprüngliche View Transitions API (Level 1) unterstützt nur same-document transitions — also Übergänge, bei denen JavaScript die DOM-Änderung koordiniert. Level 2 bringt cross-document transitions für Multi-Page-Apps, ohne JavaScript. Aktiviert wird das Feature in CSS mit @view-transition { navigation: auto; } — diese einzige Zeile reicht aus, damit der Browser beim Navigieren zwischen Seiten derselben Origin automatisch die View Transitions API verwendet.

Cross-document transitions funktionieren über die pageswap und pagereveal-Ereignisse, die auf dem window-Objekt gefeuert werden. Mit pageswap kann man die ausgehende Seite für den Snapshot vorbereiten, mit pagereveal die eingehende Seite. Über event.viewTransition in beiden Events erhält man Zugriff auf das ViewTransition-Objekt und kann Animationen anpassen oder überspringen. Für Navigationstypen (Vorwärts, Rückwärts, Reload) liefert die Navigation API die Information, sodass man richtungsabhängige Animationen implementieren kann.

Die Navigation API und die View Transitions API sind eng miteinander verknüpft. Die Navigation API ermöglicht es, Navigationsereignisse abzufangen und den Transition-Typ zu bestimmen — Vorwärts-Navigation, Rückwärts-Navigation (Back/Forward), Reload. Basierend auf diesem Typ können unterschiedliche CSS-Animationen ausgelöst werden. Das klassische Beispiel: Vorwärts-Navigation zeigt einen Links-zu-Rechts-Slide, Rückwärts-Navigation zeigt den Reverse-Slide. Dies war früher nur mit komplexen SPA-Routing-Bibliotheken möglich.

Für MPA-Übergänge setzt man den Transition-Typ über die types-Option in startViewTransition() oder über das pageswap/pagereveal-Event. Im CSS verwendet man :active-view-transition-type() um richtungsabhängige Animationen zu definieren. Dieser Ansatz ersetzt das JavaScript-basierte Routing für Animation-Zwecke vollständig — die Businesslogik des Routings bleibt im Server-Rendering, die Animation liegt vollständig in CSS.


/* MPA Cross-Document View Transitions — pure CSS approach */

/* Enable cross-document transitions for same-origin navigation */
@view-transition {
  navigation: auto;
}

/* Default: cross-fade (built-in, nothing needed) */

/* Direction-aware transitions using :active-view-transition-type() */
:root:active-view-transition-type(forward) {
  &::view-transition-old(root) {
    animation: slide-out-to-left 0.35s ease-in-out both;
  }
  &::view-transition-new(root) {
    animation: slide-in-from-right 0.35s ease-in-out both;
  }
}

:root:active-view-transition-type(backward) {
  &::view-transition-old(root) {
    animation: slide-out-to-right 0.35s ease-in-out both;
  }
  &::view-transition-new(root) {
    animation: slide-in-from-left 0.35s ease-in-out both;
  }
}

@keyframes slide-out-to-left   { to   { transform: translateX(-100%); } }
@keyframes slide-in-from-right { from { transform: translateX(100%);  } }
@keyframes slide-out-to-right  { to   { transform: translateX(100%);  } }
@keyframes slide-in-from-left  { from { transform: translateX(-100%); } }

/* Respect user motion preferences */
@media (prefers-reduced-motion: reduce) {
  ::view-transition-old(root),
  ::view-transition-new(root) {
    animation-duration: 0.01ms !important;
  }
}

8. MPA vs. SPA View Transitions im Vergleich

Die Wahl zwischen MPA und SPA View Transitions hängt von der Architektur des Projekts ab. MPA Cross-Document Transitions (Level 2) sind die einfachere Lösung für server-gerenderte Seiten: kein JavaScript, nur @view-transition { navigation: auto; } und das CSS. SPA-Transitions mit startViewTransition() bieten mehr Kontrolle, erfordern aber JavaScript-Koordination jeder DOM-Änderung.

Merkmal SPA (Level 1) MPA (Level 2) Empfehlung
JavaScript nötig Ja (startViewTransition) Nein (nur CSS) MPA für SSR-Projekte
Shared Elements Ja Ja (Chrome 126+) Beide unterstützt
Browser-Support 2026 Chrome 111+, FF 136+ Chrome 126+, FF 136+ Progressive Enhancement
Richtungs-Animationen Via JS + types Via pageswap/CSS types MPA eleganter
Daten-Abruf vor Transition Async Callback Nicht möglich SPA für dynamische Inhalte

9. Accessibility und prefers-reduced-motion

Jede View Transition-Implementierung muss prefers-reduced-motion respektieren. Nutzer, die Bewegungsreduktion aktiviert haben, können durch intensive Seitenübergangs-Animationen Übelkeit oder Orientierungslosigkeit erleiden. Die korrekte Implementierung: In einem @media (prefers-reduced-motion: reduce)-Block werden alle View-Transition-Animationen entweder deaktiviert oder auf einen einfachen Fade reduziert. Eine animation-duration: 0.01ms auf den ::view-transition-old und ::view-transition-new Pseudoelementen eliminiert effektiv jede Bewegung.

Darüber hinaus sollte man sicherstellen, dass View Transitions keine inhaltlichen Informationen verbergen oder verzögern. Screen Reader dürfen nicht durch aktive Transitions blockiert werden — das ist in der aktuellen Browser-Implementierung korrekt gehandhabt, sollte aber bei komplexen asynchronen Transitions im SPA-Kontext explizit getestet werden. Das finished-Promise des ViewTransition-Objekts kann genutzt werden, um nach Abschluss der Transition den Fokus korrekt zu setzen.

Mironsoft

View Transitions, Hyvä-Theme-Entwicklung und moderne CSS-Architekturen

View Transitions in Magento und Hyvä implementieren?

Wir integrieren die View Transitions API in Hyvä-Themes und Magento-Frontends — für nahtlose Produktseiten-Übergänge, animierte Kategorienavigation und eine App-ähnliche Nutzererfahrung ohne JavaScript-Framework-Overhead.

MPA-Transitions

@view-transition für Magento-MPA — kein JavaScript, rein CSS-basierte Seitenübergänge

Shared Elements

Produkt-Bilder und Titel fliegen nahtlos von der Listing- zur Detailseite

Accessibility

prefers-reduced-motion, Fokus-Management und WCAG-konforme Transition-Implementierung

10. Zusammenfassung

Die View Transitions API ist eine der bedeutendsten Frontend-Innovationen der letzten Jahre. Sie ermöglicht nahtlose Seitenübergänge — inklusive animierter Shared Elements — für sowohl Single-Page-Apps als auch Multi-Page-Apps. Mit view-transition-name werden Elemente identifiziert, die "herüberfliegen" sollen. Die CSS-Pseudoelemente ::view-transition-old() und ::view-transition-new() geben volle Kontrolle über Timing und Easing. Für MPA-Projekte reicht @view-transition { navigation: auto; }, um Cross-Document-Transitions zu aktivieren — ohne JavaScript.

Der Progressive-Enhancement-Ansatz ist klar: In nicht unterstützenden Browsern findet ein normaler Seitenwechsel statt — funktional einwandfrei. In unterstützenden Browsern (Chrome 111+/126+ für MPA, Firefox 136+) läuft die Animation. prefers-reduced-motion muss in jeder Implementierung respektiert werden. Für Hyvä-Themes und Magento-MPA-Frontends ist die MPA-Variante die direkteste Lösung: minimales CSS, keine Framework-Abhängigkeiten, maximale Performance.

View Transitions API — Das Wichtigste auf einen Blick

MPA aktivieren

@view-transition { navigation: auto; } — eine CSS-Zeile aktiviert Cross-Document-Transitions für same-origin Navigation.

Shared Elements

view-transition-name: eindeutiger-name auf altem und neuem Element. Browser berechnet FLIP-Animation automatisch.

CSS-Kontrolle

::view-transition-old(name) und ::view-transition-new(name) für individuelle Keyframe-Animationen. ::view-transition-group für Positions-Animation.

Accessibility

@media (prefers-reduced-motion: reduce) mit animation-duration: 0.01ms für alle ::view-transition-Pseudoelemente. Pflicht.

11. FAQ: CSS View Transitions API

1Was ist die View Transitions API?
Browser-API für nahtlose Animationen beim DOM-Wechsel oder Seitenwechsel. Snapshot vor/nach der Änderung, Animation über CSS-Pseudoelemente steuerbar.
2MPA-Transitions aktivieren?
@view-transition { navigation: auto; } — eine CSS-Zeile. Browser nutzt automatisch View Transitions bei same-origin Navigation. Kein JavaScript nötig.
3Was ist view-transition-name?
CSS-Property für Shared Elements. Gleicher eindeutiger Name auf alter und neuer Seite → Browser animiert FLIP-Übergang automatisch von alter zu neuer Position/Größe.
4Zwei Elemente mit gleichem Namen?
Transition bricht ab. Namen müssen eindeutig sein. Für Listen: dynamisch mit ID generieren — 'card-' + item.id.
5Richtungs-Slide-Animation?
:active-view-transition-type(forward/backward) in CSS. Verschiedene Keyframes für ::view-transition-old und ::view-transition-new je nach Richtung.
6Browser-Support 2026?
SPA: Chrome 111+, Firefox 136+, Safari 18+. MPA: Chrome 126+, Firefox 136+. Progressive Enhancement via @supports.
7prefers-reduced-motion?
@media (prefers-reduced-motion: reduce): animation-duration: 0.01ms !important auf ::view-transition-old und ::view-transition-new. Pflicht für Accessibility.
8Async startViewTransition()?
Callback kann Promise zurückgeben. Browser wartet auf Auflösung (Datenabruf), dann neuer Snapshot und Animation. Ideal für SPA-Datenabrufe vor DOM-Update.
9Dynamische Listen-Namen?
element.style.viewTransitionName = 'card-' + item.id — einmalig beim Rendern. Nicht während der Transition setzen, um Eindeutigkeit zu gewährleisten.
10::view-transition-old und -new?
Pseudoelemente für Snapshot-Bilder. Mit CSS Keyframes animierbar — individuelles Timing, Easing und Transforms pro benanntem Transition-Teilnehmer.