Gepubliceerd: 22 sep. 2025
Wanneer u een weergaveovergang start, maakt de browser automatisch snapshots voor en na van elementen die zijn gemarkeerd met een view-transition-name
. Deze snapshots worden weergegeven in een boomstructuur van pseudo-elementen. Standaard is de gegenereerde boomstructuur "plat". Dit betekent dat de oorspronkelijke hiërarchie in de DOM verloren gaat en alle vastgelegde weergaveovergangsgroepen onder één pseudo-element ::view-transition
vallen.
Deze flat tree-aanpak is voor veel toepassingen voldoende, maar er zijn enkele stylingtoepassingen die hiermee niet haalbaar zijn. Hieronder volgen voorbeelden van effecten die een onverwacht visueel effect kunnen hebben in een flat tree:
- Clipping (
overflow
,clip-path
,border-radius
): clipping heeft invloed op de onderliggende elementen van het element, wat betekent dat de onderliggende elementen van de weergaveovergangsgroep elkaar niet kunnen knippen. -
opacity
,mask-image
enfilter
: deze effecten zijn ontworpen om te werken op een volledig gerasterde afbeelding van een boom, waarbij ze de onderliggende elementen beïnvloeden in plaats van elk item afzonderlijk. - 3D-transformaties (
transform-style
,transform
,perspective
): om het volledige scala aan 3D-transformatie-animaties weer te geven, moet een zekere hiërarchie worden gehandhaafd.
Het volgende voorbeeld toont een platte pseudoboom met elementen die zijn bijgesneden door een voorouder in de DOM-boom. Deze elementen verliezen hun bijsnijding tijdens de weergaveovergang, wat resulteert in een gebroken visueel effect.
Geneste weergave-overgangsgroepen zijn een uitbreiding op weergave-overgangen waarmee u ::view-transition-group
pseudo-elementen in elkaar kunt nesten. Wanneer weergave-overgangsgroepen genest zijn, is het mogelijk om effecten zoals clipping tijdens de overgang te herstellen.
Browser Support
Van een platte pseudoboom naar een geneste pseudoboom
In de volgende demo kun je op de avatar van een persoon klikken om meer informatie over die persoon te zien. De animaties worden verzorgd door een overgang in dezelfde documentweergave, waarbij de aangeklikte knop wordt omgezet in het dialoogvenster, de avatar en naam over het scherm worden verplaatst en de alinea's in het dialoogvenster omhoog of omlaag worden geschoven.
Live demo
Demo-opname
Demo-opname (vertraagd)
Als u de demo goed bekijkt, ziet u dat er een probleem is met de overgang: hoewel de alinea's met de beschrijving kinderen zijn van het <dialog>
-element in de DOM, wordt de tekst niet afgekapt door het <dialog>
-vak tijdens de overgang:
<dialog id="info_bramus" closedby="any">
<h2><img alt="…" class="avatar" height="96" width="96" src="avatar_bramus.jpg"> <span>Bramus</span></h2>
<p>Bramus is …</p>
<p>…</p>
</dialog>
overflow: clip
op de <dialog>
doet ook niets.
Het probleem is de manier waarop weergaveovergangen hun pseudoboom opbouwen en weergeven:
- In de pseudoboom zijn alle snapshots standaard broers of zussen van elkaar.
- De pseudoboom wordt weergegeven in een pseudo-element
::view-transition
dat over het gehele document heen wordt weergegeven.
Specifiek voor deze demo ziet de DOM-boom er als volgt uit:
html
├─ ::view-transition
│ ├─ ::view-transition-group(card)
│ │ └─ ::view-transition-image-pair(card)
│ │ ├─ ::view-transition-old(card)
│ │ └─ ::view-transition-new(card)
│ ├─ ::view-transition-group(name)
│ │ └─ ::view-transition-image-pair(name)
│ │ ├─ ::view-transition-old(name)
│ │ └─ ::view-transition-new(name)
│ ├─ ::view-transition-group(avatar)
│ │ └─ ::view-transition-image-pair(avatar)
│ │ ├─ ::view-transition-old(avatar)
│ │ └─ ::view-transition-new(avatar)
│ ├─ ::view-transition-group(paragraph1.text)
│ │ └─ ::view-transition-image-pair(paragraph1.text)
│ │ └─ ::view-transition-new(paragraph1.text)
│ └─ ::view-transition-group(paragraph2.text)
│ └─ ::view-transition-image-pair(paragraph2.text)
│ └─ ::view-transition-new(paragraph2.text)
├─ head
└─ body
└─ …
Omdat de pseudo's ::view-transition-group(.text)
opeenvolgende broers of zussen zijn van de pseudo ::view-transition-group(card)
worden ze bovenop de kaart geschilderd.
Om ::view-transition-group(card)
::view-transition-group(.text)
te laten knippen, moeten de pseudo's ::view-transition-group(.text)
kinderen zijn van de ::view-transition-group(card)
. Gebruik hiervoor view-transition-group
, waarmee u een "bovenliggende groep" kunt toewijzen aan een gegenereerd pseudo-element ::view-transition-group()
.
Om de bovenliggende groep te wijzigen, hebt u twee opties:
- Stel op de bovenliggende site de
view-transition-group
incontain
, zodat deze alle onderliggende sites met eenview-transition-name
bevat. - Stel voor alle onderliggende items de
view-transition-group
in op deview-transition-name
van de bovenliggende item. U kunt ooknearest
gebruiken om de dichtstbijzijnde vooroudergroep te targeten.
Voor deze demo wordt de code voor het gebruik van geneste weergave-overgangsgroepen:
button.clicked,
dialog {
view-transition-group: contain;
}
Of
button.clicked,
dialog *,
view-transition-group: nearest;
}
Met deze code worden de pseudo's ::view-transition-group(.text)
nu genest binnen de pseudo ::view-transition-group(card)
. Dit gebeurt in een extra pseudo ::view-transition-group-children(…)
, die alle geneste pseudo's bij elkaar houdt:
html
├─ ::view-transition
│ ├─ ::view-transition-group(card)
│ │ ├─ ::view-transition-image-pair(card)
│ │ │ ├─ ::view-transition-old(card)
│ │ │ └─ ::view-transition-new(card)
│ │ └─::view-transition-group-children(card)
│ │ ├─ ::view-transition-group(paragraph1.text)
│ │ │ └─ ::view-transition-image-pair(paragraph1.text)
│ │ │ └─ ::view-transition-new(paragraph1.text)
│ │ └─ ::view-transition-group(paragraph2.text)
│ │ └─ ::view-transition-image-pair(paragraph2.text)
│ │ └─ ::view-transition-new(paragraph2.text)
│ ├─ ::view-transition-group(name)
│ │ └─ ::view-transition-image-pair(name)
│ │ ├─ ::view-transition-old(name)
│ │ └─ ::view-transition-new(name)
│ └─ ::view-transition-group(avatar)
│ └─ ::view-transition-image-pair(avatar)
│ ├─ ::view-transition-old(avatar)
│ └─ ::view-transition-new(avatar)
├─ head
└─ body
└─ …
Om ten slotte de ::view-transition-group(card)
pseudo de alinea's te laten knippen, past u overflow: clip
op de ::view-transition-group-children(card)
pseudo:
::view-transition-group-children(card) {
overflow: clip;
}
Het resultaat is als volgt:
Live demo
Demo-opname
Demo-opname (vertraagd)
De pseudo-element ::view-transition-group-children
is alleen aanwezig wanneer geneste groepen worden gebruikt. De grootte ervan is gelijk aan de border-box van het oorspronkelijke element en de rand is transparant met dezelfde vorm en randdikte als het element dat het pseudo-element genereerde ( card
in het vorige voorbeeld).
Knippen en meer
Geneste weergave-overgangsgroepen worden ook gebruikt voor andere doeleinden dan knipeffecten. Een ander voorbeeld zijn 3D-effecten. In de volgende demo is er een optie om de kaart tijdens de overgang in 3D te roteren.
html:active-view-transition-type(open) {
&::view-transition-old(card) {
animation-name: rotate-out;
}
&::view-transition-new(card) {
animation-name: rotate-in;
}
}
html:active-view-transition-type(close) {
&::view-transition-old(card) {
animation-name: rotate-in;
}
&::view-transition-new(card) {
animation-name: rotate-out;
}
}
Zonder geneste weergaveovergangsgroepen roteren de avatar en de naam niet mee met de kaart.
Live demo
Demo-opname
Demo-opname (vertraagd)
Door de avatar- en naampseudo's in de kaart te nesten, kun je het 3D-effect herstellen. Maar dat is niet het enige wat je moet doen. Naast het roteren van de pseudo's ::view-transition-old(card)
en ::view-transition-new(card)
, moet je ook de pseudo's ::view-transition-group-children(card)
roteren.
html:active-view-transition-type(open) {
&::view-transition-group-children(card) {
animation: rotate-in var(--duration) ease;
backface-visibility: hidden;
}
}
html:active-view-transition-type(close) {
&::view-transition-group-children(card) {
animation: rotate-out var(--duration) ease;
backface-visibility: hidden;
}
}
Live demo
Demo-opname
Demo-opname (vertraagd)
Meer demo's
In het volgende voorbeeld worden geneste weergave-overgangsgroepen gebruikt om ervoor te zorgen dat de kaarten worden bijgesneden door hun voorouderlijke scroller. U kunt het gebruik van geneste weergave-overgangsgroepen in- of uitschakelen met de meegeleverde bedieningselementen.
Live demo
Demo-opname
Het interessante aan deze demo is dat alle ::view-transition-group(.card)
pseudo's genest worden in – en geknipt worden door – de voorouder ::view-transition-group(cards)
pseudo. De #targeted-card
pseudo is uitgesloten omdat de in-/uitstapanimatie niet geknipt mag worden door de ::view-transition-group(cards)
.
/* The .cards wrapper contains all children */
.cards {
view-transition-name: cards;
view-transition-group: contain;
}
/* Contents that bleed out get clipped */
&::view-transition-group-children(cards) {
overflow: clip;
}
/* Each card is given a v-t-name and v-t-class */
.card {
view-transition-name: match-element;
view-transition-class: card;
}
/* The targeted card is given a unique name (to style the pseudo differently)
and shouldn't be contained by the ::view-transition-group-children(cards) pseudo */
#targeted-card {
view-transition-name: targeted-card;
view-transition-group: none;
}
Samenvatten
Met geneste weergaveovergangen kunt u een deel van de topologie van de DOM-boom behouden tijdens het construeren van de pseudo-elementen. Dit ontsluit diverse effecten die voorheen niet mogelijk waren met weergaveovergangen, waarvan we er hier enkele hebben beschreven.
Nesten verandert het model voor de constructie van weergaveovergangen en is bedoeld om geavanceerde effecten te creëren. Zoals opgemerkt, kunnen weergaveovergangen met elementbereik ook een deel van de effecten met een eenvoudiger model bereiken. We raden u aan beide functies uit te proberen om te bepalen welke het beste bij u past.