Gepubliceerd: 27 maart 2026
Element-scoped view transitions maken het mogelijk om meerdere view transitions tegelijkertijd uit te voeren, lopende view transitions in elkaar te nesten en z-index op te lossen die je mogelijk tegenkomt bij document-scoped view transitions – en dat alles terwijl de rest van de pagina interactief blijft. Lees deze handleiding om te leren hoe je ze gebruikt.
De behoefte aan meer gerichte overgangen tussen weergaven.
Wanneer je een weergaveovergang binnen hetzelfde document start met document.startViewTransition() (of via de tegenhanger ervan voor overgangen tussen documenten ), beperkt de browser de resulterende weergaveovergang tot het document.
Nadat de update-callback is uitgevoerd en de browser een momentopname heeft gemaakt van alle benodigde elementen, wordt de resulterende ::view-transition overlay en de bijbehorende boomstructuur van pseudo-elementen gekoppeld aan het :root element, in het volgende voorbeeld html .
html
├─ ::view-transition
│ └─ ::view-transition-group(root)
│ └─ ::view-transition-image-pair(root)
│ ├─ ::view-transition-old(root)
│ └─ ::view-transition-new(root)
├─ head
└─ body
└─ …
Omdat de ::view-transition laag bovenop de overgangsroot wordt weergegeven, kan dit tot onverwachte situaties leiden. Elementen die deelnemen aan een weergaveovergang kunnen bijvoorbeeld plotseling andere elementen overlappen die er niet aan deelnemen, of elementen worden mogelijk niet langer afgesneden door hun voorouderwrapper tijdens de weergaveovergang.
Live demonstratie
Demo-opname
Het opnieuw inschakelen pointer-events bij ::view-transition of het gebruik van geneste view-transition-groepen kan sommige neveneffecten verhelpen die document-scoped view-transitions met zich meebrengen. Deze methoden bieden echter geen oplossing voor alle problemen.
Elementen met position: fixed of popovers worden bijvoorbeeld nog steeds verduisterd door een document-scoped view transition zolang de transition actief is — ook wel bekend als het z-index probleem .
Schakel de pop-up in de volgende demo in en uit en selecteer vervolgens de knop 'Schudden' om een weergaveovergang op documentniveau te starten. Geneste weergaveovergangsgroepen lossen het knipprobleem op, maar het probleem met de lagen blijft bestaan.
Live demonstratie
Demo-opname
Een mogelijke oplossing is om de popover vast te leggen als onderdeel van de weergaveovergang door deze een view-transition-name te geven. Hoewel dit voor een enkele instantie zou kunnen werken, is het omslachtig om te onderhouden en belast het het momentopnameproces onnodig.
Weergaveovergangen op elementniveau
Met element-scoped view transitions kun je een view transition starten op een subboom van de DOM. In plaats van document.startViewTransition() aan te roepen, roep je element.startViewTransition() aan op een willekeurig element, waardoor de view transition beperkt blijft tot dat element.
In het volgende codefragment start de browser een weergaveovergang die beperkt is tot het <ul> -element.
document.querySelector('ul').startViewTransition({
callback: () => {
// … code that manipulates the contents of <ul>
},
})
Het element waarop je element.startViewTransition() aanroept —bijvoorbeeld de <ul> —wordt de overgangsroot of het bereik genoemd.
Wanneer de browser een weergaveovergang beperkt tot een element, wordt dit element geïsoleerd van de rest van de DOM:
- De browser zoekt alleen naar elementen om een momentopname van te maken binnen de substructuur van het bereik.
- Tijdens het momentopnameproces – terwijl de
updatecallback wordt uitgevoerd – stopt alleen het renderen van de scope. - De resulterende
::view-transitionpseudo-boom wordt in de overgangswortel geïnjecteerd.
Met de <ul> ziet de DOM-structuur er bijvoorbeeld zo uit terwijl de weergaveovergang actief is:
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
De ::view-transition pseudo heeft dezelfde grootte en vorm als de transition root en wordt alleen bovenop de transition root weergegeven. Hierdoor wordt de gelaagde volgorde van elementen buiten de transition root gerespecteerd.
Als je bijvoorbeeld een popover hebt die boven het <ul> -element zichtbaar is en je vervolgens een element-scoped view transition start op het <ul> -element, wordt de popover niet verduisterd door de pseudo-tree van de view transition.
Probeer het eens uit in de volgende demo. Deze heeft twee knoppen. De eerste knop opent of sluit de popover, en de tweede knop herschikt de lijstitems met behulp van een element-specifieke weergaveovergang.
Live demonstratie
Demo-opname
Omdat er gebruik wordt gemaakt van element-scoped view transitions, blijft de popover zichtbaar boven het <ul> -element zolang de overgang actief is.
Bovendien blijven de elementen buiten het <ul> -element, zoals bijvoorbeeld de knoppen, interactief, omdat deze elementen geen deel uitmaken van het bereik.
Zelfdeelnemende scopes en geneste weergaveovergangsgroepen
Wanneer je een weergaveovergang start op een element dat de overloop afknipt (dat wil zeggen, wanneer de overflow is ingesteld op hidden , scroll of clip ), merk je dat de inhoud van de weergaveovergang visueel afgesneden blijft.
Dit komt doordat element-scoped view transitions het volgende automatisch afhandelen:
- De scope krijgt automatisch
view-transition-name: roottoegepast, waardoor deze zelfparticipatief wordt. - Het bereik krijgt automatisch
view-transition-group: containtoegepast om geneste weergaveovergangsgroepen mogelijk te maken. - De resulterende
::view-transition-group-children(root)pseudo wordt automatisch afgekapt metoverflow: clipals de scope root de overflow afkapt, waardoor wordt voorkomen dat de pseudo's visueel buiten de transition root vallen.
Hierdoor kunt u de CSS die u gebruikt met element-specifieke weergaveovergangen alleen richten op de elementen die u wilt vastleggen. In de lijstdemo voegt de CSS bijvoorbeeld alleen namen toe aan de lijstitems:
ul li {
view-transition-name: match-element;
view-transition-class: album;
}
Probeer het eens uit in de volgende demo. Hiermee kun je zelfparticipatie overrulen. Wanneer de scope zelfparticipatie heeft (het standaardgedrag), werkt alles zoals verwacht. Wanneer de scope geen zelfparticipatie heeft, verandert de rand ervan onmiddellijk en loopt de inhoud ervan tijdens de overgang buiten de wrapper.
Live demonstratie
Demo-opname
Ter referentie ziet de pseudo-boom voor deze demo met zelfparticipatie er als volgt uit:
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
Omdat de overgangsbasis, het <ul> -element, de inhoud verticaal afknipt, past ::view-transition-group-children(root) ook automatisch een afknip toe.
Gelijktijdige weergaveovergangen op elementniveau
Omdat elementgebonden weergaveovergangen geïsoleerd van elkaar worden uitgevoerd, kunnen meerdere elementgebonden weergaveovergangen tegelijkertijd worden uitgevoerd als ze een verschillende scope hebben.
De volgende demo bevat twee knoppen om de volgorde van de lijsten te wijzigen, één voor elke lijst. Elke knop start een element-specifieke weergaveovergang, maar alleen voor de betreffende lijst. Omdat de DOM-structuren van beide lijsten elkaar niet overlappen, kunnen de twee element-specifieke weergaveovergangen tegelijkertijd en onafhankelijk van elkaar worden uitgevoerd.
Live demonstratie
Demo-opname
Door dit geïsoleerde karakter kunt u de waarden view-transition-name hergebruiken in verschillende scopes. Zolang een naam uniek blijft binnen zijn scope, is er geen conflict.
Geneste element-scoped weergaveovergangen en de containment van weergaveovergangsnamen
Wanneer de DOM-structuren van meerdere element-specifieke weergaveovergangen elkaar overlappen, bestaat het risico op een conflict tussen de waarden view-transition-name . Om die reden kent de browser automatisch view-transition-scope: all toe aan actieve element-specifieke weergaveovergangen om dit risico te beperken.
Net zoals anchor-scope anchor-name waarden beperkt, zorgt de view-transition-scope eigenschap ervoor dat view-transition-name waarden beperkt blijven tot de subboom van het element. De eigenschap accepteert none , een lijst met namen die je wilt beperken, of all om alle waarden te beperken.
Naast het voorkomen dat namen buiten beeld vallen, voorkomt view-transition-scope ook dat een element en de inhoud ervan worden vastgelegd door een gelijktijdige, externe weergaveovergang. Wanneer het snapshotproces de subboom doorloopt om een element te vinden om een snapshot van te maken, negeert het elementen (en hun volledige subboom) waarop view-transition-scope: all is toegepast. Dit gaat ervan uit dat die elementen al deelnemen aan een andere weergaveovergang met elementbereik.
De volgende demo is een variant op de vorige. Naast de twee knoppen om de lijstinhoud te schudden, is er ook een knop 'Swap' om de lijsten om te wisselen. Het wisselen gebeurt door de klasse .reversed op de #lists-wrapper aan of uit te zetten.
Live demonstratie
Demo-opname
Omdat view-transition-scope: all automatisch wordt toegepast tijdens de shuffle-overgang, kunt u een gelijktijdige, externe swap-overgang starten terwijl de shuffle-overgang nog gaande is.
Omdat view-transition-scope: all er ook voor zorgt dat een element niet wordt vastgelegd in een buitenste overgang, voegt de demo ook view-transition-name waarden toe aan de elementen die de <ul> elementen omhullen.
#list1-wrapper, #list2-wrapper {
view-transition-name: attr(id type(<custom-ident>));
}
De pseudo-boom voor deze demo ziet er als volgt uit, nadat de tweede lijst is geschud en beide lijsten zijn verwisseld:
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
Leer meer
Voor meer informatie over element-scoped view transitions, zie de uitleg , de css-view-transitions-2 specificatie en de lijst met openstaande specificatiewijzigingen .