Data di pubblicazione: 22 settembre 2025
Quando avvii una transizione di visualizzazione, il browser acquisisce automaticamente istantanee prima e dopo degli elementi taggati con un view-transition-name. Queste istantanee vengono visualizzate in un albero di pseudo-elementi. Per impostazione predefinita, l'albero generato è "piatto". Ciò significa che la gerarchia originale nel DOM viene persa e tutti i gruppi di transizione di visualizzazione acquisiti sono elementi di pari livello sotto un singolo pseudo-elemento ::view-transition.
Questo approccio ad albero piatto è sufficiente per molti casi d'uso, ma non per alcuni casi d'uso di stile. Di seguito sono riportati alcuni esempi di effetti che possono avere un effetto visivo imprevisto in un albero piatto:
- Ritaglio (
overflow,clip-path,border-radius): il ritaglio influisce sugli elementi secondari dell'elemento, il che significa che gli elementi di pari livello del gruppo di transizione della visualizzazione non possono ritagliarsi a vicenda. opacity,mask-imageefilter: analogamente, questi effetti sono progettati per funzionare su un'immagine completamente rasterizzata di un albero, interessando gli elementi secondari, anziché ogni elemento singolarmente.- Trasformazioni 3D (
transform-style,transform,perspective): per visualizzare l'intera gamma di animazioni di trasformazione 3D, è necessario mantenere una certa gerarchia.
L'esempio seguente mostra uno pseudo-albero piatto, con elementi ritagliati da un predecessore nell'albero DOM. Questi elementi perdono il ritaglio durante la transizione della visualizzazione, con un effetto visivo non corretto.
I gruppi di transizioni di visualizzazione nidificati sono un'estensione delle transizioni di visualizzazione che consente di nidificare gli pseudo-elementi ::view-transition-group l'uno nell'altro. Quando i gruppi di transizione di visualizzazione sono nidificati, è possibile ripristinare effetti come il ritaglio durante la transizione.
Browser Support
Da uno pseudo-albero piatto a uno pseudo-albero nidificato
Nella demo seguente puoi fare clic sull'avatar di una persona per visualizzare ulteriori informazioni su di lei. Le animazioni sono gestite da una transizione di visualizzazione dello stesso documento che trasforma il pulsante selezionato nella finestra di dialogo, sposta l'avatar e il nome sullo schermo e fa scorrere i paragrafi della finestra di dialogo verso l'alto o verso il basso.
Demo live
Registrazione di demo
Demo Recording (Slowed down)
Se osservi attentamente la demo, noterai un problema con la transizione: anche se i paragrafi con la descrizione sono elementi secondari dell'elemento <dialog> nel DOM, il testo non viene ritagliato dalla casella di <dialog> durante la transizione:
<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>
Anche l'applicazione di overflow: clip su <dialog> non ha alcun effetto.
Il problema è il modo in cui le transizioni di visualizzazione creano ed eseguono il rendering del loro pseudo-albero:
- Nello pseudo-albero, per impostazione predefinita, tutti gli snapshot sono elementi di pari livello.
- Lo pseudo-albero viene visualizzato in uno pseudo-elemento
::view-transitionche viene visualizzato sopra l'intero documento.
In particolare, per questa demo, l'albero DOM è il seguente:
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
└─ …
Poiché gli pseudo-elementi ::view-transition-group(.text) sono elementi di pari livello successivi dello pseudo-elemento ::view-transition-group(card), vengono visualizzati sopra la scheda.
Per fare in modo che ::view-transition-group(card) ritagli ::view-transition-group(.text), gli pseudo-elementi ::view-transition-group(.text) devono essere elementi secondari di ::view-transition-group(card). A questo scopo, utilizza view-transition-group, che ti consente di assegnare un "gruppo principale" per uno pseudo-elemento ::view-transition-group() generato.
Per modificare il gruppo principale, hai due opzioni:
- Sulla risorsa principale, imposta
view-transition-groupsucontain, in modo che contenga tutte le risorse secondarie con unview-transition-name. - Su tutti gli elementi secondari, imposta
view-transition-groupsuview-transition-namedell'elemento principale. Puoi anche utilizzarenearestper scegliere come target il gruppo di livello superiore più vicino.
Quindi, per questa demo, per utilizzare i gruppi di transizioni di visualizzazione nidificati, il codice diventa:
button.clicked,
dialog {
view-transition-group: contain;
}
Oppure
button.clicked,
dialog *,
view-transition-group: nearest;
}
Con questo codice, gli pseudo-elementi ::view-transition-group(.text) vengono nidificati all'interno dello pseudo-elemento ::view-transition-group(card). Questo viene fatto in uno pseudo ::view-transition-group-children(…) aggiuntivo, che raggruppa tutti gli pseudo nidificati:
html
├─ ::view-transition
│ ├─ ::view-transition-group(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-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)
├─ head
└─ body
└─ …
Infine, per fare in modo che lo pseudo-elemento ::view-transition-group(card) ritagli i paragrafi, applica overflow: clip allo pseudo-elemento ::view-transition-group-children(card):
::view-transition-group-children(card) {
overflow: clip;
}
Il risultato è il seguente:
Demo live
Registrazione di demo
Demo Recording (Slowed down)
Lo pseudo ::view-transition-group-children è presente solo quando vengono utilizzati gruppi nidificati. Le sue dimensioni corrispondono alla casella del bordo dell'elemento originale e gli viene assegnato un bordo trasparente con la stessa forma e lo stesso spessore del bordo dell'elemento che ha generato lo pseudo-elemento, ovvero card nell'esempio precedente.
Ritaglio e altro ancora
I gruppi di transizioni di visualizzazione nidificati vengono utilizzati in posizioni diverse dagli effetti di ritaglio. Un altro esempio sono gli effetti 3D. Nella demo seguente è presente un'opzione per ruotare la scheda in 3D durante la transizione.
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;
}
}
Senza gruppi di transizioni di visualizzazione nidificati, l'avatar e il nome non ruotano insieme alla scheda.
Demo live
Registrazione di demo
Demo Recording (Slowed down)
Se nidifichi gli pseudo-elementi avatar e nome all'interno della scheda, l'effetto 3D può essere ripristinato. Ma non è l'unica cosa che devi fare. Oltre a ruotare gli pseudo ::view-transition-old(card) e ::view-transition-new(card), devi anche ruotare ::view-transition-group-children(card).
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;
}
}
Demo live
Registrazione di demo
Demo Recording (Slowed down)
Altre demo
Nell'esempio seguente, i gruppi di transizioni di visualizzazione nidificati vengono utilizzati per garantire che le schede vengano ritagliate dal relativo scroller predecessore. Puoi attivare o disattivare l'utilizzo di gruppi di transizioni di visualizzazione nidificati utilizzando i controlli inclusi.
Demo live
Registrazione di demo
La cosa interessante di questa demo è che tutti gli pseudo-elementi ::view-transition-group(.card) vengono nidificati all'interno dello pseudo-elemento predecessore ::view-transition-group(cards) e ritagliati da quest'ultimo. L'elemento #targeted-card è escluso perché la sua animazione di entrata/uscita non deve essere ritagliata dall'elemento ::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;
}
Riepilogo
Le transizioni di visualizzazione nidificate ti consentono di preservare parte della topologia dell'albero DOM durante la creazione degli pseudo-elementi. In questo modo si sblocca una serie di effetti che prima non erano possibili con le transizioni di visualizzazione, alcuni dei quali sono descritti qui.
La nidificazione modifica il modello di creazione delle transizioni di visualizzazione ed è pensata per essere utilizzata per creare effetti avanzati. Come già accennato, anche le transizioni di visualizzazione con ambito elemento possono ottenere un sottoinsieme degli effetti con un modello più semplice. Ti invitiamo a provare entrambe le funzionalità per decidere quale si adatta meglio alle tue esigenze.