Publicado el 27 de marzo de 2026
Las transiciones de vista con alcance de elemento permiten que se ejecuten varias transiciones de vista de forma simultánea, permiten que las transiciones de vista en curso se aniden dentro de otra y resuelven los problemas de z-index que podrías encontrar con las transiciones de vista con alcance de documento, todo mientras se mantiene interactivo el resto de la página. Lee esta guía para aprender a usarlas.
La necesidad de transiciones de vista con un alcance más reducido
Cuando inicias una transición de vista del mismo documento con document.startViewTransition() (o a través de su contraparte entre documentos), el navegador limita la transición de vista resultante al documento.
Después de que se ejecuta la devolución de llamada de actualización y el navegador toma instantáneas de todos los elementos necesarios, la superposición ::view-transition resultante y su árbol de pseudoelementos se adjuntan al elemento :root, html en el siguiente ejemplo.
html
├─ ::view-transition
│ └─ ::view-transition-group(root)
│ └─ ::view-transition-image-pair(root)
│ ├─ ::view-transition-old(root)
│ └─ ::view-transition-new(root)
├─ head
└─ body
└─ …
Debido a que la capa ::view-transition se renderiza sobre la raíz de la transición, esto puede generar situaciones inesperadas. Por ejemplo, los elementos que participan en una transición de vista pueden superponerse repentinamente a otros que no participan, o los elementos ya no pueden ser recortados por su wrapper superior durante la transición de vista.
Demostración en directo
Grabación de la demostración:
Volver a habilitar pointer-events en ::view-transition o usar grupos de transiciones de vista anidadas puede resolver algunos efectos secundarios que introducen las transiciones de vista con alcance de documento. Sin embargo, estos métodos no pueden resolver todos los problemas.
Por ejemplo, los elementos con position: fixed o los elementos emergentes aún están ocultos por una transición de vista con alcance de documento mientras la transición está activa, también conocida como el z-index problema.
Activa o desactiva el elemento emergente en la siguiente demostración y, luego, selecciona el botón Shuffle para iniciar una transición de vista con alcance de documento. Los grupos de transiciones de vista anidadas resuelven el problema de recorte, pero el problema de capas permanece.
Demostración en directo
Grabación de la demostración:
Una solución alternativa es capturar el popover como parte de la transición de vista dándole un view-transition-name. Si bien esto podría funcionar para una sola instancia, es difícil de mantener y exige innecesariamente el proceso de instantáneas.
Transiciones de vista con alcance de elemento
Las transiciones de vista con alcance de elemento te permiten iniciar una transición de vista en un subárbol del DOM. En lugar de llamar a document.startViewTransition(), llamas a element.startViewTransition() en un elemento arbitrario, que limita la transición de vista a ese elemento.
En el siguiente fragmento, el navegador inicia una transición de vista con alcance de elemento en el elemento <ul>.
document.querySelector('ul').startViewTransition({
callback: () => {
// … code that manipulates the contents of <ul>
},
})
El elemento en el que invocas element.startViewTransition(), por ejemplo, <ul>, se denomina raíz de transición o alcance.
Cuando el navegador limita una transición de vista a un elemento, se aísla del resto del DOM:
- El navegador busca elementos para tomar instantáneas solo dentro del subárbol del alcance.
- Durante el proceso de instantáneas, mientras se ejecuta la devolución de llamada
update, solo se detiene la renderización del alcance. - El pseudoárbol
::view-transitionresultante se inserta en la raíz de la transición.
Por ejemplo, con el <ul>, el árbol DOM se ve de la siguiente manera mientras la transición de vista está activa:
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
El pseudo ::view-transition tiene el mismo tamaño y forma que la raíz de la transición, y solo se renderiza sobre ella. Por este motivo, se respeta el orden de las capas de los elementos fuera de la raíz de la transición.
Por ejemplo, si tienes un elemento emergente que está visible sobre el elemento <ul> y, luego, inicias una transición de vista con alcance de elemento en el elemento <ul>, el elemento emergente no está oculto por el pseudoárbol de la transición de vista.
En la siguiente demostración, pruébalo. Tiene dos botones. El primer botón activa o desactiva el elemento emergente, y el segundo botón reordena los elementos de la lista con una transición de vista con alcance de elemento.
Demostración en directo
Grabación de la demostración:
Debido a que se usan transiciones de vista con alcance de elemento, el elemento emergente permanece visible sobre el elemento <ul> mientras la transición está activa.
Además, los elementos fuera del elemento <ul>—por ejemplo, los botones—siguen siendo interactivos, ya que esos elementos no forman parte del alcance.
Alcances de participación automática y grupos de transiciones de vista anidadas
Cuando inicias una transición de vista con alcance de elemento en un elemento que recorta su desbordamiento (es decir, cuando su overflow se establece en hidden, scroll o clip), observas que el contenido de la transición de vista permanece recortado visualmente.
Esto se debe a que las transiciones de vista con alcance de elemento controlan lo siguiente automáticamente:
- El alcance obtiene automáticamente
view-transition-name: rootaplicado, lo que lo hace participar automáticamente. - El alcance obtiene automáticamente
view-transition-group: containaplicado para habilitar grupos de transiciones de vista anidadas. - El pseudo
::view-transition-group-children(root)resultante recorta automáticamente su contenido conoverflow: clipsi la raíz del alcance recorta su desbordamiento, lo que evita que los pseudos se desborden visualmente de la raíz de la transición.
Como resultado, puedes mantener el CSS que usas con las transiciones de vista con alcance de elemento enfocadas solo en los elementos que deseas capturar. Por ejemplo, en la demostración de la lista, el CSS solo agrega nombres a los elementos de la lista:
ul li {
view-transition-name: match-element;
view-transition-class: album;
}
En la siguiente demostración, pruébalo. Te permite anular la participación automática. Cuando el alcance es de participación automática (el comportamiento predeterminado), todo funciona como se espera. Cuando el alcance no es de participación automática, su borde cambia de inmediato y su contenido se desborda del wrapper durante la transición.
Demostración en directo
Grabación de la demostración:
Como referencia, el pseudoárbol de esta demostración con participación automática se ve de la siguiente manera:
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
Debido a que la raíz de la transición, el elemento <ul>, recorta verticalmente su contenido, el ::view-transition-group-children(root) también aplica automáticamente un recorte.
Transiciones de vista con alcance de elemento simultáneas
Debido a que las transiciones de vista con alcance de elemento se ejecutan de forma aislada, se pueden ejecutar varias transiciones de vista con alcance de elemento de forma simultánea si tienen un alcance diferente.
La siguiente demostración tiene dos botones de reordenamiento, uno para cada lista. Cada botón inicia una transición de vista con alcance de elemento solo en su lista respectiva. Debido a que los árboles DOM de ambas listas no se superponen, las dos transiciones de vista con alcance de elemento pueden ejecutarse de forma simultánea de forma aislada.
Demostración en directo
Grabación de la demostración:
Esta naturaleza aislada también te permite reutilizar los valores view-transition-name en diferentes alcances. Mientras un nombre siga siendo único dentro de su alcance, no habrá conflicto.
Transiciones de vista con alcance de elemento anidadas y contención de view-transition-name
Cuando los árboles DOM de varias transiciones de vista con alcance de elemento se superponen, existe el riesgo de colisión de valores view-transition-name. Por este motivo, el navegador asigna automáticamente view-transition-scope: all a las transiciones de vista con alcance de elemento activas para mitigar este riesgo.
De manera similar a cómo anchor-scope limita los valores anchor-name, la propiedad view-transition-scope garantiza que los valores view-transition-name se limiten al subárbol del elemento. La propiedad acepta none, una lista de nombres que deseas limitar o all para limitar todos los valores.
Además de evitar que los nombres se desborden, view-transition-scope también evita que un elemento y su contenido sean capturados por una transición de vista externa y simultánea. Cuando el proceso de instantáneas atraviesa el subárbol para encontrar un elemento para tomar una instantánea, ignora los elementos (y todo su subárbol) que tienen aplicado view-transition-scope: all. Esto supone que esos elementos ya participan en una transición de vista con alcance de elemento diferente.
La siguiente demostración es una variación de la anterior. Además de los dos botones que mezclan el contenido de la lista, también tiene un botón Swap para intercambiar las listas. Activar o desactivar una clase .reversed en el #lists-wrapper controla el intercambio.
Demostración en directo
Grabación de la demostración:
Debido a que view-transition-scope: all se aplica automáticamente durante la transición de mezcla, puedes iniciar una transición de intercambio externa y simultánea mientras la transición de mezcla aún está en curso.
Debido a que view-transition-scope: all también evita que se tome una instantánea de un elemento en una transición externa, la demostración también agrega valores view-transition-name a los elementos que envuelven los elementos <ul>.
#list1-wrapper, #list2-wrapper {
view-transition-name: attr(id type(<custom-ident>));
}
El pseudoárbol de esta demostración, después de iniciar una mezcla en la segunda lista y, luego, intercambiar ambas listas, se ve de la siguiente manera:
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
Más información
Para obtener más información sobre las transiciones de vista con alcance de elemento, consulta la explicación, la especificación css-view-transitions-2 y la lista de ediciones de especificaciones abiertas.