Page B

CSS View Transitions — Named Elements

Transition effect

Next Page

Scoping to one element

By default the entire page is one snapshot. Giving an element a view-transition-name tells the browser to capture it separately so you can animate just that element while the rest of the page stays frozen.

/* Both pages must declare the same name */
main {
  view-transition-name: main-content;
}

/* Freeze the root so header/footer don't move */
::view-transition-old(root),
::view-transition-new(root) {
  animation: none;
}

Custom keyframes

Target the named element's pseudo-elements to apply your own animations:

::view-transition-old(main-content) {
  animation: slide-out 0.4s ease-in both;
}

::view-transition-new(main-content) {
  animation: slide-in 0.4s ease-out both;
}

::view-transition-group(main-content) {
  overflow: clip; /* prevent scrollbar during slide */
}

The pseudo-element tree

During a transition the browser builds this overlay structure:

::view-transition                 /* full-screen overlay */
  ::view-transition-group(root)     /* one per named element */
    ::view-transition-image-pair(root)
      ::view-transition-old(root)    /* outgoing snapshot */
      ::view-transition-new(root)    /* incoming snapshot */
  ::view-transition-group(main-content)
    ::view-transition-image-pair(main-content)
      ::view-transition-old(main-content)
      ::view-transition-new(main-content)

The rule for names

The view-transition-name must match on both the outgoing and incoming page for the browser to connect the two snapshots and animate between them. A mismatch means the element fades in/out independently rather than morphing.

Names must also be unique per page — no two elements can share the same name at the same time or the transition is skipped entirely for those elements.