Shared Element Transitions

Shared Element Transitions is a proposal for a new script API that allows a simple set of transitions in both Single-Page Applications (SPAs) and Multi-Page Applications (MPAs).

The inspiration for this feature are transitions similar to the ones listed in the Material Design Principles.

The intent is to support transitions similar to Android Activity Transitions.

Root Transitions

The proposal can be split into two parts: a root transition, and a shared element transition. As an example of a root transition, consider the following snippet of code:

function changeBodyBackground() {
  document.body.style = "background: blue";
}

function handleTransition() {
  const transition = document.createPageTransition({
    rootTransition: "reveal-left",
    duration: 300
  });

  transition.prepare().then(() => {
    changeBodyBackground();
    transition.start();
  });
}

If script simply calls changeBodyBackground(), then the body element's background will change to blue. The change will appear on the next visual frame. However, if script calls handleTransition(), then the following steps happen:

  • We create a page transition with a "reveal-left" root transition, and a 300ms transition duration.
  • We prepare the transition, which asynchronously saves a copy of the pixels currently present on the screen. When saving is done, the promise resolves.
  • After the promise resolves, we call changeBodyBackground(), which changes the body element's background to blue, and begin the transition.
  • Because the effect specified is "reveal-left", the saved pixels slide to the left, revealing the new blue background body on the page.

Note that to accomplish a similar effect as a polyfill, the script would need to make a copy of the whole page, or draw to canvas, in order to have seemingly two copies of the DOM. One copy would slide and another one be revealed with some changes.

Below is a video of some of the sample transitions: Video Link for Shared Element Transitions

A similar effect could be achieved in the MPA casee, although the API is likely to differ slightly.

Supported Effects

The following is a list of effects that could be supported for root transitions. Note that this list is not comprehensive.

  • reveal-left: old content slides from center in the specified direction, revealing new content.
  • reveal-right
  • reveal-up
  • reveal-down
  • cover-left: new content slides from an edge in the specified direction, covering old content.
  • cover-right
  • cover-up
  • cover-down
  • explode: old content "explodes" by growing and becoming more transparent, revealing new content.
  • implode: new content "implodes" by shrinking from a large side and becoming opaque, convering old content.

Shared Element Transitions

Note that if a set of shared elements could be specified, then the User-Agent could also transition the shared elements independently on the root transition. The effect would be that the shared elements go from the old location to the new location while root transition takes place.

The above example API may change to include a sequence of elements that need to be shared, both in the prepare and the start phases:

  transition.prepare([element1, element2]).then(() => {
    changeBodyBackground();
    transition.start([element1, element2]);
  });

This means that the elements specified in the prepare call automatically transition to the location and place of elements corresponding elements specified in the start call.

In the example above, the same elements specified so the intended effect is for those elements to remain in place while the changed background is revealed by old background sliding left.

TODO: Add example video.

Previous Efforts

There have been prior efforts in this space, ranging from APIs proposed for the web platform to effects like IE5 transition effects that were removed. We believe that the current proposal aligns web development with native mobile development by bringing similar transition capabilities to the web platform.

Alternatives

SPA Polyfill

The proposed API for a Single-Page App should, in theory, be polyfillable by a javascript library. This is because script has access to all of the elements and effects that would be used in the transition.

However, we believe that this is hard to do. For instance, to achieve the effect of the example page transition with only the background change, script would have need to figure out how to visually present two copies of content (other than the background color) and transition them.

Furthermore, a polyfill would not be able to do the transition across Multiple-Page Apps.

Other resources

Brief explainer in docs