Veröffentlicht: 27. März 2026
Mit elementbezogenen Ansichtsübergängen können mehrere Ansichtsübergänge gleichzeitig ausgeführt werden. Außerdem können laufende Ansichtsübergänge ineinander verschachtelt werden. So lassen sich z-index-Probleme beheben, die bei dokumentbezogenen Ansichtsübergängen auftreten können. Der Rest der Seite bleibt dabei interaktiv. In diesem Leitfaden erfahren Sie, wie Sie sie verwenden.
Notwendigkeit von Ansichtsübergängen mit engerem Umfang
Wenn Sie mit document.startViewTransition() (oder dem dokumentübergreifenden Pendant) einen Ansichtsübergang im selben Dokument starten, wird der resultierende Ansichtsübergang vom Browser auf das Dokument beschränkt.
Nachdem der Update-Callback ausgeführt wurde und der Browser alle erforderlichen Elemente erfasst hat, wird das resultierende ::view-transition-Overlay und sein Baum von Pseudoelementen an das :root-Element angehängt, im folgenden Beispiel html.
html
├─ ::view-transition
│ └─ ::view-transition-group(root)
│ └─ ::view-transition-image-pair(root)
│ ├─ ::view-transition-old(root)
│ └─ ::view-transition-new(root)
├─ head
└─ body
└─ …
Da die ::view-transition-Ebene über dem Übergangs-Root gerendert wird, kann dies zu unerwarteten Situationen führen. Beispielsweise können Elemente, die an einem Ansichtsübergang beteiligt sind, plötzlich andere Elemente überlappen, die nicht beteiligt sind. Oder Elemente werden während des Ansichtsübergangs nicht mehr von ihrem übergeordneten Wrapper abgeschnitten.
Live-Demo
Demo-Aufzeichnung
Durch Reaktivieren von pointer-events auf ::view-transition oder Verwenden von verschachtelten Ansichtsübergangsgruppen können einige Nebenwirkungen behoben werden, die durch Ansichtsübergänge auf Dokumentebene entstehen. Mit diesen Methoden lassen sich jedoch nicht alle Probleme lösen.
Elemente mit position: fixed oder Pop-overs werden beispielsweise weiterhin durch einen dokumentbezogenen Ansichtsübergang verdeckt, während der Übergang aktiv ist. Dies wird auch als das z-index-Problem bezeichnet.
Aktivieren Sie das Pop-over in der folgenden Demo und wählen Sie dann die Schaltfläche Shuffle (Zufällige Reihenfolge) aus, um eine Ansichtsübergang auf Dokumentebene zu starten. Verschachtelte Ansichtsübergangsgruppen beheben das Clipping-Problem, das Problem mit den Ebenen bleibt jedoch bestehen.
Live-Demo
Demo-Aufzeichnung
Eine Problemumgehung besteht darin, die popover als Teil des Ansichtsübergangs zu erfassen, indem Sie ihr eine view-transition-name geben. Das mag für eine einzelne Instanz funktionieren, ist aber umständlich und belastet den Snapshot-Prozess unnötig.
View-Übergänge mit Elementbereich
Mit Ansichtsübergängen auf Elementebene können Sie einen Ansichtsübergang für einen Teilbaum des DOM starten. Anstatt document.startViewTransition() aufzurufen, rufen Sie element.startViewTransition() für ein beliebiges Element auf. Dadurch wird der Ansichtsübergang auf dieses Element beschränkt.
Im folgenden Snippet startet der Browser einen Übergang vom Typ „Aufruf“ für das Element <ul>.
document.querySelector('ul').startViewTransition({
callback: () => {
// … code that manipulates the contents of <ul>
},
})
Das Element, in dem Sie element.startViewTransition() aufrufen, z. B. <ul>, wird als Übergangsstamm oder Bereich bezeichnet.
Wenn der Browser eine Ansichtsübergang auf ein Element beschränkt, wird es vom Rest des DOM isoliert:
- Der Browser sucht nur im Unterbaum des Bereichs nach Elementen, von denen ein Snapshot erstellt werden soll.
- Während des Snapshot-Vorgangs, also während der
update-Callback ausgeführt wird, wird nur das Rendern des Bereichs angehalten. - Der resultierende
::view-transition-Pseudobaum wird in den Übergangs-Root eingefügt.
Mit dem <ul> sieht der DOM-Baum beispielsweise so aus, während der Ansichtsübergang aktiv ist:
html
├─ head
└─ body
├─ ul
│ ├─ ::view-transition
│ │ └─ ::view-transition-group(root)
│ │ ├─ ::view-transition-group-children(root)
│ │ │ └─ …
│ │ └─ ::view-transition-image-pair(root)
│ │ ├─ ::view-transition-old(root)
│ │ └─ ::view-transition-new(root)
│ ├─ li
│ ├─ li
│ └─ li
├─ button#showpopover
├─ button#reorder
└─ div#popover
└─ p
Das ::view-transition-Pseudo hat dieselbe Größe und Form wie der Übergangs-Root und wird nur über dem Übergangs-Root gerendert. Daher wird die Reihenfolge der Ebenen von Elementen außerhalb des Übergangs-Roots berücksichtigt.
Wenn Sie beispielsweise ein Pop-over haben, das über dem <ul>-Element sichtbar ist, und dann eine Ansichtsübergang mit Elementbereich für das <ul>-Element starten, wird das Pop-over nicht durch den Pseudobaum des Ansichtsübergangs verdeckt.
Probieren Sie es in der folgenden Demo aus. Es hat zwei Tasten. Mit der ersten Schaltfläche wird das Pop-over ein- und ausgeblendet. Mit der zweiten Schaltfläche werden die Listenelemente mithilfe eines elementbezogenen Ansichtsübergangs neu angeordnet.
Live-Demo
Demo-Aufzeichnung
Da Ansichtsübergänge mit Elementbereich verwendet werden, bleibt das Pop-over während des Übergangs über dem <ul>-Element sichtbar.
Außerdem bleiben die Elemente außerhalb des <ul>-Elements, z. B. die Schaltflächen, interaktiv, da sie nicht Teil des Bereichs sind.
Selbstbeteiligende Bereiche und verschachtelte Ansichtsübergangsgruppen
Wenn Sie einen elementbezogenen Ansichtsübergang für ein Element starten, bei dem der Überlauf abgeschnitten wird (d. h. wenn overflow auf hidden, scroll oder clip festgelegt ist), werden die Inhalte des Ansichtsübergangs weiterhin visuell abgeschnitten.
Das liegt daran, dass elementbezogene Ansichtsübergänge Folgendes automatisch verarbeiten:
- Der Bereich wird automatisch mit
view-transition-name: rootangewendet, wodurch er selbst teilnimmt. - Der Bereich wird automatisch mit
view-transition-group: containangewendet, um verschachtelte Ansichtsübergangsgruppen zu aktivieren. - Das resultierende
::view-transition-group-children(root)-Pseudoelement schneidet seinen Inhalt automatisch mitoverflow: clipzu, wenn die Bereichs-Root ihren Überlauf abschneidet. So wird verhindert, dass die Pseudoelemente visuell aus der Übergangs-Root herausragen.
So können Sie das CSS, das Sie für Ansichtsübergänge mit Elementbereich verwenden, nur auf die Elemente konzentrieren, die Sie erfassen möchten. Im Listendemo werden beispielsweise nur Namen zu den Listenelementen hinzugefügt:
ul li {
view-transition-name: match-element;
view-transition-class: album;
}
Probieren Sie es in der folgenden Demo aus. Sie können die Selbstbeteiligung überschreiben. Wenn der Umfang selbstbeteiligend ist (Standardverhalten), funktioniert alles wie erwartet. Wenn der Rahmen nicht selbst teilnimmt, ändert sich seine Begrenzung sofort und sein Inhalt läuft während des Übergangs aus dem Wrapper heraus.
Live-Demo
Demo-Aufzeichnung
Zur Orientierung: Der Pseudobaum für diese Demo mit Selbstbeteiligung sieht so aus:
html
├─ head
└─ body
├─ ul
│ ├─ ::view-transition
│ │ └─ ::view-transition-group(root)
│ │ ├─ ::view-transition-group-children(root)
│ │ │ ├─ ::view-transition-group(item1)
│ │ │ │ └─ ::view-transition-image-pair(item1)
│ │ │ │ ├─ ::view-transition-old(item1)
│ │ │ │ └─ ::view-transition-new(item1)
│ │ │ ├─ ::view-transition-group(item2)
│ │ │ │ └─ …
│ │ │ …
│ │ └─ ::view-transition-image-pair(root)
│ │ ├─ ::view-transition-old(root)
│ │ └─ ::view-transition-new(root)
│ ├─ li
│ ├─ li
│ └─ li
└─ button#reorder
Da das Übergangsstammelement (<ul>) seine Inhalte vertikal beschneidet, wird auch für das ::view-transition-group-children(root) automatisch ein Clip angewendet.
Gleichzeitige elementbezogene Ansichtsübergänge
Da Ansichtsübergänge mit Elementbereich isoliert ausgeführt werden, können mehrere Ansichtsübergänge mit Elementbereich gleichzeitig ausgeführt werden, wenn sie einen anderen Bereich haben.
Im folgenden Beispiel gibt es zwei Schaltflächen zum Neuanordnen, eine für jede Liste. Mit jeder Schaltfläche wird nur für die jeweilige Liste ein elementbezogener Ansichtsübergang gestartet. Da sich die DOM-Bäume der beiden Listen nicht überschneiden, können die beiden elementbezogenen Ansichtsübergänge gleichzeitig und isoliert ausgeführt werden.
Live-Demo
Demo-Aufzeichnung
Außerdem können Sie view-transition-name-Werte in verschiedenen Bereichen wiederverwenden. Solange ein Name innerhalb seines Bereichs eindeutig bleibt, gibt es keinen Konflikt.
Verschachtelte Ansichtsübergänge mit Elementbereich und Containment von „view-transition-name“
Wenn sich die DOM-Bäume mehrerer elementbezogener Ansichtsübergänge überschneiden, besteht das Risiko einer view-transition-name-Wertkollision. Aus diesem Grund weist der Browser aktiven elementbezogenen Ansichtsübergängen automatisch view-transition-scope: all zu, um dieses Risiko zu minimieren.
Ähnlich wie anchor-scope-Bereiche anchor-name-Werte eingrenzen, sorgt die view-transition-scope-Property dafür, dass view-transition-name-Werte auf den Unterbaum des Elements beschränkt werden. Für die Property wird none akzeptiert, eine Liste mit Namen, die Sie eingrenzen möchten, oder all, um alle Werte einzugrenzen.
view-transition-scope verhindert nicht nur, dass Namen überlaufen, sondern auch, dass ein Element und sein Inhalt von einer äußeren, gleichzeitigen Ansichtsübergang erfasst werden. Wenn beim Erstellen von Snapshots der Unterbaum durchlaufen wird, um ein Element für den Snapshot zu finden, werden Elemente (und ihr gesamter Unterbaum) mit view-transition-scope: all ignoriert. Dabei wird davon ausgegangen, dass diese Elemente bereits an einem anderen elementbezogenen Ansichtsübergang beteiligt sind.
Die folgende Demo ist eine Variante der vorherigen. Neben den beiden Schaltflächen zum Mischen des Listeninhalts gibt es auch die Schaltfläche Tauschen, mit der die Listen getauscht werden können. Durch das Umschalten einer .reversed-Klasse für das #lists-wrapper wird der Tausch vorgenommen.
Live-Demo
Demo-Aufzeichnung
Da view-transition-scope: all automatisch während des Übergangs zum Shuffle angewendet wird, können Sie einen gleichzeitigen, äußeren Tauschübergang starten, während der Übergang zum Shuffle noch läuft.
Da view-transition-scope: all auch verhindert, dass ein Element in einem äußeren Übergang als Snapshot aufgenommen wird, werden in der Demo den Elementen, die die <ul>-Elemente umschließen, auch view-transition-name-Werte hinzugefügt.
#list1-wrapper, #list2-wrapper {
view-transition-name: attr(id type(<custom-ident>));
}
Der Pseudobaum für diese Demo sieht nach dem Starten einer zufälligen Wiedergabe in der zweiten Liste und dem anschließenden Tauschen beider Listen so aus:
html
├─ head
└─ body
└─ #lists-wrapper.reversed (SCOPE)
├─ ::view-transition
│ └─ ::view-transition-group(lists-wrapper)
│ ├─ ::view-transition-group-children(lists-wrapper)
│ │ ├─ ::view-transition-group(list1-wrapper)
│ │ │ └─ ::view-transition-image-pair(list1-wrapper)
│ │ │ ├─ ::view-transition-old(list1-wrapper)
│ │ │ └─ ::view-transition-new(list1-wrapper)
│ │ └─ ::view-transition-group(list2-wrapper)
│ │ └─ ::view-transition-image-pair(list2-wrapper)
│ │ ├─ ::view-transition-old(list2-wrapper)
│ │ └─ ::view-transition-new(list2-wrapper)
│ └─ ::view-transition-image-pair(lists-wrapper)
│ ├─ ::view-transition-old(lists-wrapper)
│ └─ ::view-transition-new(lists-wrapper)
├─ div#list1-wrapper
│ ├─ ul
│ │ ├─ li#item1
│ │ ├─ li#item2
│ │ └─ li#item3
│ └─ button.reorder
└─ div#list2-wrapper
├─ ul (SCOPE)
│ ├─ ::view-transition
│ │ └─ ::view-transition-group(list)
│ │ ├─ ::view-transition-group-children(list )
│ │ │ ├─ ::view-transition-group(item4)
│ │ │ │ └─ ::view-transition-image-pair(item4)
│ │ │ │ ├─ ::view-transition-old(item4)
│ │ │ │ └─ ::view-transition-new(item4)
│ │ │ ├─ ::view-transition-group(item5)
│ │ │ │ └─ …
│ │ │ …
│ │ └─ ::view-transition-image-pair(list)
│ │ ├─ ::view-transition-old(list)
│ │ └─ ::view-transition-new(list)
│ ├─ li#item4
│ ├─ li#item5
│ └─ li#item6
└─ button.reorder
Weitere Informationen
Weitere Informationen zu View-Übergängen mit Elementbereich finden Sie in der Erklärung, in der Spezifikation „css-view-transitions-2“ und in der Liste der offenen Spezifikationsänderungen.