Signatur
Beschreibung
document.startViewTransition() animiert Zustandswechsel innerhalb einer Seite, z. B. beim Routenwechsel in einer Single-Page-Application, beim Filtern einer Liste oder beim Umschalten zwischen Hell- und Dunkelmodus. Der Browser macht zuerst einen Schnappschuss des aktuellen Zustands, ruft dann Ihren Rückruf auf, der das DOM ändert, und erstellt danach einen Schnappschuss des neuen Zustands. Zwischen beiden blendet er standardmäßig über (Cross-Fade).
Die Animation lässt sich vollständig per CSS steuern, und zwar über die Pseudo-Elemente ::view-transition, ::view-transition-group(name), ::view-transition-old(name) und ::view-transition-new(name). Elemente, die mit view-transition-name einen eindeutigen Namen bekommen, werden einzeln animiert. Sie „wandern“ dann von ihrer alten an die neue Position und Größe (Shared-Element-Transition).
Der Rückruf darf synchron sein oder ein Promise zurückgeben, etwa nach einem fetch(). Solange das Promise nicht erfüllt ist, bleibt die Seite eingefroren, denn das Rendering pausiert. Das zurückgegebene ViewTransition-Objekt stellt die Promises updateCallbackDone, ready und finished bereit sowie die Methode skipTransition(). Mit ready lassen sich zusätzlich eigene Animationen per Web Animations API an die Pseudo-Elemente hängen.
Statt eines Rückrufs kann man auch ein Optionsobjekt mit update und types übergeben. Die Typen lassen sich in CSS mit :active-view-transition-type(...) abfragen, zum Beispiel für unterschiedliche Animationen beim Vorwärts- und Rückwärts-Navigieren.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $updateCallback | () => void | Promise<void> | null | Funktion, die das DOM auf den neuen Zustand bringt. Sie wird aufgerufen, nachdem der alte Zustand festgehalten wurde. Gibt sie ein Promise zurück, wartet die Transition, bis es erfüllt ist. |
| $options | { update?: Function, types?: string[] } | Alternative zum Rückruf. update entspricht updateCallback. types ist eine Liste von Transitionstypen, die in CSS mit :active-view-transition-type() abgefragt werden können (Chrome 125+, Safari 18.2+). |
Rückgabewert
updateCallbackDone, ready und finished, die Methode skipTransition() und die Eigenschaft types (ein ViewTransitionTypeSet).Beispiele
Theme-Wechsel mit Feature-Erkennung
const toggleTheme = () => {
const update = () => document.documentElement.classList.toggle('dark');
// Fallback: Ohne Unterstützung wird das DOM direkt und ohne Animation geändert
if (!document.startViewTransition) {
update();
return;
}
document.startViewTransition(update);
};
document.querySelector('#theme-btn').addEventListener('click', toggleTheme);
SPA-Navigation mit asynchronem Laden und Promise-Status
const navigate = async (url) => {
const loadAndRender = async () => {
const res = await fetch(url);
const html = await res.text();
document.querySelector('main').innerHTML = html; // Inhalt nur aus vertrauenswürdiger Quelle!
};
if (!document.startViewTransition) return loadAndRender();
const transition = document.startViewTransition(loadAndRender);
try {
await transition.updateCallbackDone;
console.log('DOM aktualisiert');
await transition.finished;
console.log('Animation beendet');
} catch (err) {
console.error('Update fehlgeschlagen:', err);
}
};
navigate('/partials/about.html');
Kreisförmige Enthüllung mit ready und Web Animations API
document.addEventListener('click', async (event) => {
if (!event.target.matches('.reveal-btn') || !document.startViewTransition) return;
const { clientX: x, clientY: y } = event;
const radius = Math.hypot(
Math.max(x, innerWidth - x),
Math.max(y, innerHeight - y)
);
const transition = document.startViewTransition(() => {
document.body.classList.toggle('alt-layout');
});
await transition.ready; // Pseudo-Elemente existieren jetzt
document.documentElement.animate(
{ clipPath: [`circle(0 at ${x}px ${y}px)`, `circle(${radius}px at ${x}px ${y}px)`] },
{ duration: 500, easing: 'ease-in', pseudoElement: '::view-transition-new(root)' }
);
});
Transitionstypen für Vor- und Zurück-Navigation
/* CSS:
html:active-view-transition-type(forwards) ::view-transition-new(root) {
animation: slide-in-right 300ms;
}
html:active-view-transition-type(backwards) ::view-transition-new(root) {
animation: slide-in-left 300ms;
}
*/
const showPage = (page, direction) => {
const transition = document.startViewTransition({
update: () => renderPage(page),
types: [direction] // 'forwards' oder 'backwards'
});
console.log([...transition.types]);
};
const renderPage = (page) => {
document.querySelector('main').textContent = `Seite ${page}`;
};
showPage(2, 'forwards');
// Wichtig · Fallstricke
- Browser-Unterstützung: Chrome/Edge ab 111, Safari ab 18, Firefox ab 144. Die Optionsform mit
typesgibt es erst in Chrome 125+ und Safari 18.2+. Prüfen Sie deshalb immer mitif (document.startViewTransition), ob die Methode vorhanden ist, und führen Sie sonst das Update direkt aus. - Eindeutige Namen: Jeder
view-transition-namedarf zur selben Zeit nur einmal im Dokument vorkommen. Kommt ein Name doppelt vor, wird die Transition übersprungen:readywird abgelehnt, das Update läuft aber trotzdem. - Eingefrorene Seite: Während der Rückruf läuft, pausiert das Rendering. Langsame Netzwerkanfragen im Rückruf wirken daher wie ein Hänger. Laden Sie Daten möglichst vorher und ändern Sie im Rückruf nur das DOM. Nach einer Zeitüberschreitung (in Chrome etwa 4 s) bricht der Browser die Transition mit einem
TimeoutErrorab. - Nur eine Transition gleichzeitig: Ein neuer Aufruf bricht eine laufende Transition ab. Deren
ready-Promise wird dann mit einemAbortErrorabgelehnt, falls es noch aussteht. - Fehlerbehandlung: Wirft der Rückruf einen Fehler, werden
updateCallbackDoneundfinishedabgelehnt. Fangen Sie das ab, sonst entstehen unbehandelte Promise-Ablehnungen. - Barrierefreiheit: Beachten Sie
prefers-reduced-motionund schalten Sie Animationen per CSS-Media-Query ab oder ab oder schwächen Sie sie ab. - Nicht verwechseln: Für Übergänge zwischen verschiedenen Dokumenten (Multi-Page-Application) dient die CSS-Regel
@view-transition { navigation: auto; }, nicht diese Methode. - Sicherheit: Wenn Sie im Rückruf
innerHTMLmit geladenem Inhalt füllen, besteht XSS-Gefahr. Verwenden Sie nur vertrauenswürdige oder bereinigte Inhalte.