Cross-Document Navigation ohne JavaScript-Framework
Seitenwechsel in klassischen Multi-Page-Anwendungen wirken meist abrupt: die alte Seite verschwindet, die neue erscheint ohne Übergang. Cross-Document View Transitions schließen diese Lücke direkt im Browser, mit wenigen Zeilen CSS, ganz ohne Single-Page-Framework und ohne zusätzliches JavaScript für den Grundfall.
Inhaltsverzeichnis
- 1. Was Cross-Document View Transitions lösen
- 2. Das @view-transition At-Rule aktivieren
- 3. Named View Transitions mit view-transition-name
- 4. Transition-Typen für unterschiedliche Navigationsrichtungen
- 5. Eigene Animationen mit ::view-transition-old und -new
- 6. JavaScript-Hooks: pageswap und pagereveal
- 7. Fallback-Strategien für Browser ohne Unterstützung
- 8. Performance und Layout-Shift bei Seitenübergängen
- 9. Cross-Document View Transitions im Vergleich
- 10. Zusammenfassung
- 11. FAQ
1. Was Cross-Document View Transitions lösen
Klassische Mehrseiten-Anwendungen laden bei jeder Navigation ein komplett neues Dokument. Der Browser verwirft die alte Seite, reserviert einen weißen Zwischenzustand und rendert die neue Seite von vorn. Genau diesen harten Schnitt beseitigen View Transitions zwischen Seiten: statt eines Blitzers zeigt der Browser eine animierte Überblendung zwischen dem letzten sichtbaren Zustand der alten Seite und dem ersten sichtbaren Zustand der neuen Seite. Für Nutzer entsteht der Eindruck einer durchgängigen Anwendung, obwohl technisch zwei separate HTML-Dokumente geladen wurden.
Bevor Cross-Document View Transitions verfügbar waren, war ein solcher Effekt nur mit erheblichem Aufwand erreichbar: entweder über eine komplette Single-Page-Architektur mit clientseitigem Routing, oder über Tricks mit iframes und manuellem State-Management. Beide Wege bringen Zusatzkomplexität, mehr JavaScript und eine größere Angriffsfläche für Bugs mit sich. Mit der nativen View Transition API für Cross-Document-Navigation bleibt die Architektur unverändert: normale Links, normale Formulare, normale Server-Responses. Die Animation liegt komplett auf der Präsentationsschicht.
Besonders wertvoll ist das für inhaltsgetriebene Projekte wie Blogs, Shops oder Dokumentationsseiten, die aus guten Gründen (SEO, Server-Rendering, Robustheit) keine SPA-Architektur wählen wollen. Cross-Document View Transitions liefern genau die Übergangsqualität, die man sonst nur von JavaScript-Frameworks kennt, ohne deren Bundle-Größe und ohne deren Router-Komplexität.
2. Das @view-transition At-Rule aktivieren
Der Einstieg in Cross-Document View Transitions ist absichtlich simpel gehalten. Es reicht eine einzige At-Rule im Stylesheet beider beteiligten Seiten: @view-transition { navigation: auto; }. Diese Regel signalisiert dem Browser, dass Navigationen innerhalb derselben Origin als View Transition behandelt werden sollen, statt als harter Seitenwechsel. Fehlt die Regel auf der Zielseite, findet keine Transition statt, selbst wenn die Startseite sie deklariert hat.
Wichtig für die Praxis: navigation: auto greift nur bei Same-Origin-Navigationen und nur bei normalen Top-Level-Dokumentwechseln, also Klicks auf Links oder Formular-Submits, nicht bei Reloads oder externen Verweisen. Für Multi-Page-Apps mit mehreren Templates lohnt es sich, die At-Rule zentral in ein gemeinsames Basis-Stylesheet zu legen, damit jede neue Seite automatisch an den Übergängen teilnimmt, ohne dass Entwickler daran denken müssen.
/* base.css — shared across all pages of the site */
@view-transition {
navigation: auto;
}
/* Optional: disable transitions for users who prefer reduced motion */
@media (prefers-reduced-motion: reduce) {
::view-transition-group(*),
::view-transition-old(*),
::view-transition-new(*) {
animation: none !important;
}
}
Ohne weitere Anpassungen liefert der Browser bereits eine Standard-Crossfade-Animation: die alte Seite blendet aus, die neue Seite blendet ein, beide leicht überlappend. Das ist der Basisfall von Cross-Document View Transitions, und für viele Projekte bereits eine spürbare Verbesserung gegenüber dem harten Refresh. Die eigentliche Stärke der View Transition API zeigt sich aber erst, wenn einzelne Elemente individuell animiert werden.
3. Named View Transitions mit view-transition-name steuern
Damit ein bestimmtes Element über die Seitengrenze hinweg als eigenständiges, animiertes Objekt behandelt wird, bekommt es einen eindeutigen Namen: view-transition-name: produkt-bild;. Findet der Browser auf der Zielseite ein Element mit demselben Namen, erzeugt er automatisch eine Morph-Animation zwischen Position, Größe und Aussehen des alten und des neuen Elements. Das ist der Kern dessen, was man landläufig als "Shared Element Transition" kennt, jetzt aber nativ und ohne JavaScript-Bibliothek für Cross-Document-Navigation verfügbar.
Ein typisches Beispiel ist eine Produktliste, die zu einer Produktdetailseite navigiert. Das Vorschaubild in der Liste bekommt denselben view-transition-name wie das große Bild auf der Detailseite. Beim Klick gleitet der Browser das Bild sichtbar von der kleinen Position zur großen Position, inklusive Größenänderung, statt es einfach verschwinden und neu erscheinen zu lassen. Wichtig ist, dass jeder Name auf einer Seite nur einmal vergeben werden darf, sonst bricht der Browser die Transition für dieses Element ab.
/* Product list page */
.product-card img {
view-transition-name: var(--vt-name);
}
/* Assign a unique name per product via inline custom property */
/* <img style="--vt-name: product-42" ...> */
/* Product detail page — same name on the hero image */
.product-hero img {
view-transition-name: var(--vt-name);
}
/* Custom crossfade duration for the named group */
::view-transition-group(product-42) {
animation-duration: 0.4s;
}
Für dynamische Namen, etwa bei einer Liste mit vielen Produkten, wird der Name meist über eine CSS-Custom-Property gesetzt, die serverseitig oder direkt im Markup pro Element unterschiedlich befüllt wird. So bleibt das CSS generisch, während jedes Element zur Laufzeit seinen eigenen, eindeutigen view-transition-name erhält. Ohne diese Technik müsste für jedes mögliche Element eine eigene CSS-Regel geschrieben werden, was bei hunderten Produkten nicht praktikabel wäre.
4. Transition-Typen für unterschiedliche Navigationsrichtungen
Nicht jede Navigation soll gleich aussehen. Ein Klick auf "weiter" in einer Galerie sollte anders wirken als ein Klick auf "zurück", und eine Navigation zu einer übergeordneten Seite anders als eine Navigation in die Tiefe. Die View Transition API erlaubt das über sogenannte Transition-Typen, die beim Navigieren gesetzt und im CSS über die :active-view-transition-type()-Pseudoklasse abgefragt werden können.
Praktisch legt man auf dem auslösenden Link einen Typ fest, etwa über document.startViewTransition({ types: ["forward"] }) in einem kleinen Navigations-Script, oder deklarativ über das kommende types-Attribut. Im Stylesheet reagiert man dann gezielt auf den aktiven Typ: bei "forward" schiebt die neue Seite von rechts herein, bei "back" von links. Diese Unterscheidung sorgt für ein räumliches Gefühl der Navigation, das reines Crossfade nicht vermitteln kann.
/* Direction-aware transitions via active transition type */
html:active-view-transition-type(forward) {
&::view-transition-old(root) {
animation: slide-out-left 0.3s ease-in both;
}
&::view-transition-new(root) {
animation: slide-in-right 0.3s ease-out both;
}
}
html:active-view-transition-type(back) {
&::view-transition-old(root) {
animation: slide-out-right 0.3s ease-in both;
}
&::view-transition-new(root) {
animation: slide-in-left 0.3s ease-out both;
}
}
@keyframes slide-in-right {
from { transform: translateX(100%); }
}
@keyframes slide-out-left {
to { transform: translateX(-100%); }
}
Der Aufwand für diese gerichteten View Transitions ist überschaubar, der Effekt aber deutlich spürbar: Nutzer erkennen sofort, ob sie sich vorwärts oder rückwärts durch eine Struktur bewegen. Gerade bei mehrstufigen Formularen, Wizard-Flows oder Bilder-Galerien lohnt sich diese Investition, weil die räumliche Orientierung direkt zur wahrgenommenen Qualität der Anwendung beiträgt.
5. Eigene Animationen mit ::view-transition-old und -new gestalten
Jede View Transition erzeugt intern einen Pseudo-Elementbaum: ::view-transition-group als Container pro benanntem Element, darunter ::view-transition-image-pair, und darin je ein ::view-transition-old und ein ::view-transition-new Snapshot. Über diese Pseudo-Elemente lässt sich jede Phase der Animation gezielt gestalten, unabhängig von der Standard-Crossfade-Animation des Browsers.
Ein häufiger Anwendungsfall: statt eines einfachen Fade soll das alte Element nach oben herausfliegen, während das neue Element von unten hereinkommt. Das erreicht man, indem man auf ::view-transition-old(name) eine eigene animation setzt und auf ::view-transition-new(name) eine andere. Wichtig ist, die Standard-Animation vorher zu deaktivieren, sonst überlagert sie die eigene Animation und das Ergebnis wirkt unruhig statt kontrolliert.
/* Custom animation for a specific named element */
::view-transition-old(headline) {
animation: 0.35s ease-in both fade-out-up;
}
::view-transition-new(headline) {
animation: 0.35s ease-out both fade-in-from-below;
}
@keyframes fade-out-up {
to { opacity: 0; transform: translateY(-24px); }
}
@keyframes fade-in-from-below {
from { opacity: 0; transform: translateY(24px); }
}
/* Group-level control: mix-blend-mode avoids the default cross-fade double flash */
::view-transition-group(headline) {
animation-duration: 0.35s;
}
::view-transition-image-pair(headline) {
isolation: isolate;
}
Ein bekannter Stolperstein ist der doppelte Flash-Effekt, der entsteht, wenn alte und neue Snapshots sich überlappen, während beide teilweise sichtbar sind. Die Kombination aus isolation: isolate auf dem Image-Pair und einer klar definierten Reihenfolge der Animationsphasen behebt das zuverlässig. Wer eigene Animationen für View Transitions baut, sollte diese Pseudo-Elemente immer im DevTools-Element-Panel inspizieren, da sie erst während einer aktiven Transition im DOM erscheinen.
6. JavaScript-Hooks: pageswap und pagereveal
Auch wenn Cross-Document View Transitions ohne jedes JavaScript funktionieren, gibt es zwei Events, die zusätzliche Kontrolle erlauben: pageswap feuert kurz bevor die alte Seite verlassen wird, pagereveal kurz nachdem die neue Seite ihren ersten Render-Frame erreicht hat. Beide liefern über event.viewTransition Zugriff auf das laufende Transition-Objekt, inklusive der Möglichkeit, Transition-Typen dynamisch zu setzen oder die Transition per skipTransition() abzubrechen.
Ein praktisches Szenario: Man möchte den Transition-Typ abhängig von der tatsächlichen Navigationsrichtung im DOM setzen, zum Beispiel basierend auf einer Breadcrumb-Tiefe, die serverseitig nicht ohne Weiteres bekannt ist. Im pageswap-Handler lässt sich das dynamisch bestimmen und über event.viewTransition.types.add("forward") an die aktive Transition anhängen, bevor sie beginnt.
// Determine transition direction from a data attribute on the clicked link
window.addEventListener('pageswap', (event) => {
if (!event.viewTransition) return;
const direction = document.activeElement?.dataset?.navDirection;
if (direction === 'back') {
event.viewTransition.types.add('back');
} else {
event.viewTransition.types.add('forward');
}
});
// React once the new page has revealed its first frame
window.addEventListener('pagereveal', async (event) => {
if (!event.viewTransition) return;
await event.viewTransition.ready;
console.log('View transition to new page is now animating');
});
Diese Events sind bewusst optional. Für die meisten View Transitions reicht das reine CSS. Sobald aber Anwendungslogik in die Übergangsentscheidung einfließen muss, etwa unterschiedliche Animationen je nach Nutzerrolle oder A/B-Test-Variante, sind pageswap und pagereveal der richtige Einstiegspunkt, ohne dass dafür ein komplettes Router-Framework nötig wäre.
7. Fallback-Strategien für Browser ohne Unterstützung
Cross-Document View Transitions sind ein progressives Enhancement per Definition. Browser, die die @view-transition At-Rule oder view-transition-name nicht kennen, ignorieren die Deklarationen einfach und zeigen den klassischen, harten Seitenwechsel. Es gibt keinen Absturz, keine fehlende Funktionalität, nur eine weniger elegante Übergangsdarstellung. Genau deshalb eignen sich View Transitions besonders gut für Produktivsysteme: das Feature kann sofort ausgerollt werden, ohne auf vollständige Browser-Abdeckung warten zu müssen.
Für Teams, die dennoch ein konsistentes Verhalten über Browser-Grenzen hinweg sicherstellen wollen, bietet sich eine Feature-Detection über @supports an, kombiniert mit einem CSS-Hinweis für Entwickler, welche Codepfade tatsächlich aktiv sind. Wichtiger ist in der Praxis aber die Kombination mit prefers-reduced-motion, denn View Transitions sind explizit Bewegungseffekte und sollten für Nutzer mit entsprechender Systemeinstellung deaktiviert werden, unabhängig von der Browser-Unterstützung selbst.
/* Feature detection: only opt in named transitions where supported */
@supports (view-transition-name: none) {
.product-card img {
view-transition-name: var(--vt-name);
}
}
/* Respect user motion preference regardless of browser support level */
@media (prefers-reduced-motion: reduce) {
@view-transition {
navigation: none;
}
}
In der Praxis reicht meist die einfache At-Rule ohne zusätzliche Feature-Detection, weil das Grundverhalten ohnehin robust degradiert. Die prefers-reduced-motion-Regel sollte aber in jedem Projekt gesetzt werden, das Cross-Document View Transitions einsetzt, denn ein automatischer Seitenübergang, der sich nicht abschalten lässt, ist für Nutzer mit vestibulären Einschränkungen eine echte Barriere.
8. Performance und Layout-Shift bei Seitenübergängen
Ein oft unterschätzter Aspekt von View Transitions ist ihr Einfluss auf wahrgenommene und tatsächliche Performance. Für die Dauer der Transition hält der Browser Snapshots von altem und neuem Seiteninhalt vor, was kurzzeitig zusätzlichen Speicher benötigt. Bei sehr großen oder bildlastigen Seiten kann das auf schwächeren Geräten zu spürbaren Rucklern führen, besonders wenn viele Elemente gleichzeitig einen eigenen view-transition-name tragen.
Die Empfehlung aus der Praxis: view-transition-name nur für Elemente vergeben, die tatsächlich einen erkennbaren Morph-Effekt brauchen, nicht pauschal für jede Bildkachel einer Liste. Für die restliche Seite reicht die Standard-Crossfade-Behandlung des Root-Elements völlig aus. Zusätzlich sollte die Ladezeit der Zielseite selbst im Blick bleiben: Eine View Transition kaschiert keinen langsamen Server, sie verzögert lediglich die sichtbare Reaktion auf den Klick um die Animationsdauer, was bei einer ohnehin langsamen Navigation die gefühlte Wartezeit sogar verlängern kann.
Ein zusätzlicher Punkt betrifft Cumulative Layout Shift: Wenn das neue Dokument während des Ladens Schriftarten nachlädt oder Bilder ohne feste Dimensionen enthält, verschiebt sich der Inhalt während der laufenden View Transition, was den positiven Eindruck des sanften Übergangs sofort wieder zunichtemacht. Feste width/height-Attribute oder aspect-ratio auf Bildern sind daher keine Kür, sondern Voraussetzung für saubere Cross-Document View Transitions.
9. Cross-Document View Transitions im Vergleich
Für die Entscheidung, ob und wie View Transitions in einem Projekt eingesetzt werden, hilft ein direkter Vergleich der verfügbaren Ansätze für animierte Seitenübergänge in klassischen Mehrseiten-Architekturen.
| Ansatz | Aufwand | JavaScript nötig | Bewertung |
|---|---|---|---|
| Cross-Document View Transitions | Gering | Optional | Nativ, progressiv, ideal für MPA |
| SPA-Router mit Transition-Library | Hoch | Zwingend | Volle Kontrolle, aber Architekturwechsel |
| iframe-basierte Overlays | Hoch | Zwingend | Fragil, SEO-Nachteile |
| CSS-Fade per Opacity-Klasse | Sehr gering | Minimal | Kein echter Cross-Fade zwischen Dokumenten |
| Kein Übergang (Standard) | Keiner | Keins | Harter Schnitt, wirkt weniger hochwertig |
Cross-Document View Transitions gewinnen diesen Vergleich für die überwiegende Zahl klassischer Mehrseiten-Projekte, weil sie den größten Effekt bei geringstem Architekturaufwand liefern. Nur wenn eine Anwendung ohnehin bereits als Single-Page-App mit eigenem Router existiert, ist eine dedizierte JavaScript-Transition-Bibliothek unter Umständen die konsequentere Wahl, weil dort clientseitiges Routing bereits Teil der Architektur ist.
Mironsoft
Moderne CSS-Architektur und Animation für Magento und Hyvä-Frontends
Seitenübergänge, die sich hochwertig anfühlen?
Wir integrieren Cross-Document View Transitions in bestehende Shop- und Content-Seiten, inklusive Named Transitions, Fallback-Strategie und Performance-Check für Core Web Vitals.
Konzeption
Navigationsflüsse analysieren und passende Transition-Typen definieren
Umsetzung
@view-transition, Named Transitions und eigene Keyframe-Animationen
Qualitätssicherung
Fallback-Tests, reduzierte Bewegung und Layout-Shift-Kontrolle
10. Zusammenfassung
Cross-Document View Transitions bringen die aus Single-Page-Apps bekannte Übergangsqualität in klassische Mehrseiten-Architekturen, ohne dass dafür ein Router oder ein zusätzliches Framework nötig wäre. Die At-Rule @view-transition { navigation: auto; } aktiviert die Basisfunktion, view-transition-name erzeugt Shared-Element-Effekte über Seitengrenzen hinweg, und die Pseudo-Elemente ::view-transition-old und ::view-transition-new erlauben vollständig eigene Animationen statt des Standard-Crossfades.
Wichtig für den produktiven Einsatz sind drei Punkte: eine klare prefers-reduced-motion-Regel, eine bewusste Auswahl der Elemente mit eigenem view-transition-name statt pauschaler Vergabe, und feste Bilddimensionen, um Layout-Shift während der Transition zu vermeiden. Da View Transitions ohne Unterstützung einfach auf den klassischen Seitenwechsel zurückfallen, ist das Feature risikofrei einsetzbar und lässt sich schrittweise ausbauen, von einer einfachen Crossfade bis zu vollständig choreografierten, gerichteten Navigationsanimationen.
View Transitions zwischen Seiten — Das Wichtigste auf einen Blick
Aktivierung
@view-transition { navigation: auto; } auf beiden beteiligten Seiten, sonst findet keine Transition statt.
Named Transitions
view-transition-name muss auf jeder Seite eindeutig sein, erzeugt Morph-Effekte zwischen gleich benannten Elementen.
Eigene Animation
::view-transition-old und ::view-transition-new ersetzen den Standard-Crossfade durch eigene Keyframes.
Sicherheit
Progressives Enhancement, kein Fehler ohne Support. prefers-reduced-motion immer respektieren.