CSS ::view-transition-image-pair() Pseudo-Element

The ::view-transition-image-pair() pseudo-element represents the container holding the old and new visual states of an element during a View Transition. It helps control how these visual representations are combined, particularly when blending and isolation are involved.

Syntax

::view-transition-image-pair(name) {
  property: value;
}

The name argument identifies the View Transition image pair to style.

For example:

::view-transition-image-pair(root) {
  isolation: isolate;
}

This applies an isolated stacking context to the image pair associated with the root transition.

To target a named element:

::view-transition-image-pair(featured-card) {
  isolation: isolate;
}

This targets the image pair for the transition group named featured-card.

To target all image pairs:

::view-transition-image-pair(*) {
  isolation: isolate;
}

The * argument matches every generated image pair.

The functional pseudo-element also supports View Transition class selectors:

::view-transition-image-pair(.cards) {
  isolation: isolate;
}

This targets image pairs associated with the View Transition class cards.

The parentheses are required, and the selector does not create an image pair by itself.

How It Works

During a View Transition, the browser captures the visual state of participating elements before and after a document update.

The browser generates temporary pseudo-elements to display these states while the transition runs.

For each transition group, the browser creates an image pair container.

The process generally follows these steps:

  1. A View Transition starts through JavaScript or an eligible navigation.
  2. The browser captures the old visual state of participating elements.
  3. The document changes to its new state.
  4. The browser prepares the new visual state.
  5. The browser generates the transition groups and their image pairs.
  6. The old and new representations animate within their image pair containers.
  7. The temporary pseudo-elements are removed when the transition finishes.

The ::view-transition-image-pair() pseudo-element does not capture images itself.

It provides the generated container for the old and new visual representations.

The browser normally handles its layout and blending behavior automatically.

View Transition Pseudo-Element Tree

The image pair occupies a specific position within the View Transition pseudo-element hierarchy.

A simplified structure looks like this:

::view-transition
  ::view-transition-group(root)
    ::view-transition-image-pair(root)
      ::view-transition-old(root)
      ::view-transition-new(root)

Each pseudo-element has a separate responsibility.

Pseudo-Element Purpose
::view-transition Contains all generated View Transition groups.
::view-transition-group() Controls the position and dimensions of a named group.
::view-transition-image-pair() Contains the old and new visual representations and isolates their blending.
::view-transition-old() Represents the old visual state.
::view-transition-new() Represents the new visual state.

The image pair is always a child of its corresponding transition group.

Its children are the old and new visual representations, when those states exist.

Each named transition group receives its own image pair.

Understanding the Image Pair

An image pair can contain two generated visual representations:

  • ::view-transition-old() represents the element's old visual state.
  • ::view-transition-new() represents the element's new visual state.

When an element exists in both states, its image pair can contain both representations.

When an element exists in only one state, the image pair contains only the corresponding old or new representation.

For example, a card that changes color during a transition has an old and new state.

The browser can blend those states to produce a smooth visual change.

By comparison, an element that is removed during a transition may have only an old representation.

An element introduced during a transition may have only a new representation.

The image pair container is still generated for the participating transition group.

It does not represent an ordinary HTML element and does not appear permanently in the document.

Targeting Named Image Pairs

The view-transition-name property identifies elements that should receive separate View Transition groups.

For example:

.featured-card {
  view-transition-name: featured-card;
}

The browser can create an image pair with the matching name:

::view-transition-image-pair(featured-card) {
  isolation: isolate;
}

Different elements can have different transition names:

.site-logo {
  view-transition-name: site-logo;
}
.featured-card {
  view-transition-name: featured-card;
}

Their image pairs can be styled separately:

::view-transition-image-pair(site-logo) {
  isolation: isolate;
}
::view-transition-image-pair(featured-card) {
  isolation: auto;
}

The first rule preserves isolation for the logo's image pair.

The second rule disables isolation for the card's image pair, which can affect how blending interacts with surrounding content.

Changing the default isolation behavior is an advanced technique and should be tested carefully.

Each participating element must have a unique transition name within a document state.

The isolation Property

The isolation property is one of the most important properties associated with ::view-transition-image-pair().

It determines whether an element creates a new stacking context for blending.

The two values are:

Value Description
auto Does not force an isolated stacking context.
isolate Creates an isolated stacking context for the image pair.

During a View Transition, the browser normally applies isolation: isolate to image pairs.

For example:

::view-transition-image-pair(root) {
  isolation: isolate;
}

This keeps blending between the old and new visual representations isolated from unrelated content.

The default isolation is important because transition images may use blending modes that differ from ordinary rendering.

For certain custom animations, isolation can be disabled:

::view-transition-image-pair(root) {
  isolation: auto;
}

This allows the image pair to participate in blending without the same isolated boundary.

Changing isolation can affect the visual result of overlapping images and should only be done when a custom transition requires it.

Blending Old and New Images

View Transitions commonly use blending and opacity animations to create smooth changes between old and new visual states.

The old image fades out while the new image fades in.

The generated image pair contains both representations during the animation.

By default, browsers use blending behavior designed to produce a smooth cross-fade.

The mix-blend-mode property can influence how overlapping transition images are combined.

For example:

::view-transition-old(root),
::view-transition-new(root) {
  mix-blend-mode: normal;
}

This requests normal blending for the old and new root images.

The image pair can also have its isolation behavior changed:

::view-transition-image-pair(root) {
  isolation: auto;
}

These changes are useful when replacing the default cross-fade with a custom animation, such as a reveal or wipe.

For most transitions, the browser's default blending and isolation should be preserved.

Changing blending without adjusting the associated animations can produce unexpected transparency or overlapping effects.

Example

The following example demonstrates a View Transition with a named image pair.

Click the button to change the card's appearance. The browser creates old and new visual representations inside the generated image pair.

HTML:

<div class="vt-image-pair-demo" id="vt-image-pair-demo">
  <div class="vt-image-pair-card">
    <strong>View Transition Image Pair</strong>
    <p>Click the button to change this card.</p>
  </div>
  <button type="button" id="vt-image-pair-toggle">Change Appearance</button>
</div>

CSS:

.vt-image-pair-demo {
  max-width: 300px;
}
.vt-image-pair-card {
  padding: 20px;
  border-radius: 6px;
  background-color: #0066cc;
  color: #fff;
  view-transition-name: image-pair-card;
}
.vt-image-pair-card p {
  margin: 8px 0 0;
  color: inherit;
}
.vt-image-pair-demo.is-alternate .vt-image-pair-card {
  border-radius: 20px;
  background-color: #333;
}
.vt-image-pair-demo button {
  margin-top: 12px;
  padding: 8px 14px;
  border: 0;
  background-color: #0066cc;
  color: #fff;
  cursor: pointer;
}
::view-transition-image-pair(image-pair-card) {
  isolation: isolate;
}
::view-transition-group(image-pair-card) {
  animation-duration: 600ms;
}

JavaScript:

const demo = document.querySelector("#vt-image-pair-demo");
const button = document.querySelector("#vt-image-pair-toggle");
button.addEventListener("click", () => {
  const update = () => demo.classList.toggle("is-alternate");
  const reduceMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
  if (document.startViewTransition && !reduceMotion) {
    document.startViewTransition(update);
  } else {
    update();
  }
});
Browser Result
View Transition Image Pair

Click the button to change this card.

Try it: Click Change Appearance to switch between the card's blue and dark backgrounds.

In supporting browsers, the browser generates a View Transition and animates between the old and new card appearances.

The view-transition-name property identifies the card as image-pair-card.

The ::view-transition-image-pair(image-pair-card) rule explicitly preserves the browser's normal isolated blending behavior.

The ::view-transition-group(image-pair-card) rule sets the animation duration to 600 milliseconds.

If View Transitions are unsupported or reduced motion is preferred, the card changes immediately.

Note: The isolation: isolate declaration normally matches the browser's default behavior. The example demonstrates how to target the image pair without changing the default blending model.

Customizing Image Transitions

Advanced View Transitions can replace the default cross-fade with custom animations.

For example, a new page state can be revealed using a clipping animation.

In such cases, the default image blending may need to be adjusted.

The following CSS disables the default image animations and changes blending behavior:

::view-transition-image-pair(root) {
  isolation: auto;
}
::view-transition-old(root),
::view-transition-new(root) {
  animation: none;
  mix-blend-mode: normal;
  display: block;
}

This configuration can be used as a starting point for a custom reveal animation.

The isolation: auto declaration removes the forced isolation of the root image pair.

The mix-blend-mode: normal declarations prevent the old and new images from using the default blending mode.

The animation: none declarations disable the default image animations so a custom animation can take control.

For example, a custom reveal can animate the new snapshot:

@keyframes reveal-new {
  from {
    clip-path: inset(0 100% 0 0);
  }
  to {
    clip-path: inset(0 0 0 0);
  }
}
::view-transition-new(root) {
  animation: 500ms ease-out both reveal-new;
}

The new visual state is progressively revealed from left to right.

When combining these rules, ensure that the old image remains visible beneath the new image during the reveal.

Custom transitions should be tested carefully because blending and stacking behavior can affect the final appearance.

Using View Transition Classes

The view-transition-class property allows multiple transition groups to share a common styling identifier.

Unlike view-transition-name, a View Transition class does not need to be unique.

For example:

.card-one {
  view-transition-name: card-one;
  view-transition-class: cards;
}
.card-two {
  view-transition-name: card-two;
  view-transition-class: cards;
}

Each card has a unique transition name, but both use the class cards.

The image pairs can be styled together:

::view-transition-image-pair(.cards) {
  isolation: isolate;
}

The dot before cards identifies a View Transition class selector.

To target a specific group:

::view-transition-image-pair(card-one) {
  isolation: auto;
}

The named selector can override the shared class styling for the matching image pair.

View Transition classes are useful when multiple components need the same transition styling without repeating rules for each name.

The class property does not create an image pair by itself. The participating elements still require transition names.

Group vs. Image Pair

The ::view-transition-group() and ::view-transition-image-pair() pseudo-elements represent different levels of the generated transition hierarchy.

Feature ::view-transition-group() ::view-transition-image-pair()
Purpose Controls the group's size, position, and movement. Contains and isolates the old and new visual representations.
Hierarchy Child of ::view-transition. Child of ::view-transition-group().
Common styling Animation duration, easing, transforms, and dimensions. Isolation and blending behavior.
Example ::view-transition-group(card) ::view-transition-image-pair(card)

For example:

::view-transition-group(card) {
  animation-duration: 500ms;
}
::view-transition-image-pair(card) {
  isolation: isolate;
}

The group controls the animation duration.

The image pair controls how its child representations are isolated for blending.

For most View Transitions, developers customize the group and old/new images while leaving the image pair's default isolation unchanged.

Supported CSS Properties

The ::view-transition-image-pair() pseudo-element is a generated box that supports applicable CSS properties.

Its primary purpose is to provide a container for the old and new visual representations.

Property Purpose
isolation Controls whether the image pair creates an isolated stacking context.
animation-duration Controls animation duration when an animation applies.
animation-delay Controls animation delay when applicable.
animation-fill-mode Controls animation styles before and after playback.
position Controls positioning of the generated box.
inset Controls offsets for a positioned image pair.
opacity Controls transparency of the entire image pair.
filter Applies visual effects to the image pair.

For example:

::view-transition-image-pair(featured-card) {
  isolation: isolate;
}

This preserves isolated blending for the named image pair.

Properties that change the generated box's positioning or dimensions should be used carefully because the browser provides default layout rules.

For most applications, custom styling of ::view-transition-group(), ::view-transition-old(), and ::view-transition-new() is more useful.

Limitations

The ::view-transition-image-pair() pseudo-element has several limitations.

  • It exists only during an active View Transition.
  • It does not initiate a View Transition.
  • It is always generated as a child of a corresponding transition group.
  • It contains only the old and new representations that exist for that group.
  • It does not permanently change the underlying HTML element.
  • Its default isolation is important for correct blending behavior.
  • Changing isolation can affect how transition images interact with surrounding content.
  • Custom layout or positioning rules can interfere with browser-generated transition rendering.
  • Support for advanced View Transition features may differ between browsers.

For example, this rule does not create a transition:

::view-transition-image-pair(card) {
  isolation: isolate;
}

A View Transition must be active, and the browser must generate a group named card before the selector can match.

Use the view-transition-name property and an appropriate transition mechanism to create the required conditions.

Accessibility Considerations

View Transitions can make visual changes easier to follow, but animation and blending effects should not reduce readability or usability.

Follow these accessibility practices:

  • Respect the user's reduced-motion preference.
  • Avoid rapid flashing or excessive visual effects.
  • Keep transitions short and predictable.
  • Maintain readable text and sufficient contrast during animations.
  • Avoid blending effects that obscure important content.
  • Ensure the page remains usable without View Transitions.
  • Preserve keyboard focus and logical navigation during document updates.
  • Test animations with different viewport sizes and accessibility settings.

For example, reduce animation durations when reduced motion is preferred:

@media (prefers-reduced-motion: reduce) {
  ::view-transition-group(*),
  ::view-transition-old(*),
  ::view-transition-new(*) {
    animation-duration: 0.01ms;
  }
}

This minimizes the duration of the generated transition animations.

For same-document transitions, JavaScript can also skip the animation entirely:

const reduceMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
if (document.startViewTransition && !reduceMotion) {
  document.startViewTransition(updatePage);
} else {
  updatePage();
}

This updates the document immediately when reduced motion is preferred or the API is unavailable.

Browser Support

The ::view-transition-image-pair() pseudo-element has a Baseline Newly available status, with support across the latest major browsers since October 2025.

It is supported in current versions of Chrome, Edge, Firefox, Safari, and other browsers implementing CSS View Transitions.

Older browser versions may not support the feature.

Support for same-document and cross-document View Transitions should be checked separately.

To check whether the browser recognizes the selector:

@supports selector(::view-transition-image-pair(root)) {
  ::view-transition-image-pair(root) {
    isolation: isolate;
  }
}

This applies the declaration only when the browser recognizes the selector.

It does not start a View Transition or guarantee that a matching image pair exists.

For same-document transitions, provide a fallback when the JavaScript API is unavailable:

if (document.startViewTransition) {
  document.startViewTransition(updatePage);
} else {
  updatePage();
}

For current compatibility information, visit Can I Use? and search for View Transitions API.

Check support for advanced features such as View Transition classes separately when using them in production.

Specifications

The ::view-transition-image-pair() pseudo-element is defined in the CSS View Transitions Module Level 1 .

The specification defines the image pair as a generated container for corresponding old and new visual representations.

Its primary purpose is to isolate blending between those representations so that their effects do not interfere with unrelated visual content.

Related features include ::view-transition, ::view-transition-group(), ::view-transition-old(), ::view-transition-new(), and the view-transition-name property.