@view-transition - At-rule CSS
Summary of characteristics of the @view-transition
at-rule
Description of the @view-transition
at-rule.
The @view-transition
at-rule enables Cross-Document View Transitions.
When pages include this directive in their styles, the passage from one page to another is done with an animation: fade effect, scrolling, etc.
Careful! Both pages must be from the same domain.
An example of what can be achieved can be seen by clicking on the links below. But several browsers do not yet support this technology. First, click on the test link to find out if the browser that you're using supports display transitions: Test Link - Demo link.
Note: The @view-transition
directive can be included in the @media
conditional directive. This allows you to activate the transitions
only if the terminal's capacities are sufficient. There is no need to test browser compatibility: if the browser is not compatible
transitions are simply not executed, but the transition from one page to another is not altered.
Refer to our tutorial on view transitions for an overview of display transitions.
Syntax and descriptors of @view-transition
.
- @view-transition: { types: fondu; }
The
types
descriptor defines the identifier for the transition. Each page can therefore use a specific transition effect. Several types can be enumerated, separated by commas./* Enable cross-page view transitions */ @view-transition {navigation:auto; types:fondu;} /* Definition of animations */ @keyframes fondu-old { from {transform:opacity(100%);} to {transform:opacity(0%);} } @keyframes fondu-new { from {transform:opacity(0%);} to {transform:opacity(100%);} } /* Applying animations to pseudo-elements */ :active-view-transition-type(fondu)::view-transition-old(root) { animation:fondu-old 2s; } :active-view-transition-type(fondu)::view-transition-new(root) { animation:fondu-new 2s; }
Overview of view transitions.
The relatively new technique of view transitions allows you to define a transition between two displays, instead of from a sudden jump from one display to another. For example, it is possible to set a fade effect between two images.
Here's an example so you can understand what we're talking about right away: a bit of Javascript code allows you to flip the playing cards by clicking on them. The first card flips over without a transition effect. The second, on the other hand, implements a display transition: a fade between the image of the map and the that of the back. Of course, this will only work if the browser you're viewing this page on supports view transitions, which is far from not guaranteed. For example, at this time (2024)
does not address this feature.
No transition effect

With a transition effect
The Javascript code itself is very simple: it simply modifies the source (src
attribute) of the img tag.
The element on which to act (the map) is passed as the el
parameter.
function turnCard(el) {
el.src='chemin/image.png';
}
To bring in the transition effect, you just have to modify the code slightly: call the processing via the startViewTransition()
method.
function turnCardVT(el) {
document.startViewTransition({
update:() => turnCard(el),
types:['root']
});
}
/* Or, for those who don't like arrow syntaxes */
function turnCardVT(el) {
document.startViewTransition({
update: function() {
turnCard(el);
},
types:['root']
});
}
So we can see that it is very easy to get a nice ergonomics with a very simple code. Here's what the browser does when it make a view transition:
- Store a copy of the initial screen as an image.
- Make the requested changes.
- Memorize a copy of the new screen, also in the form of an image.
- Start an animation on the starting frame and the final frame.
The ::view-transition-old()
and ::view-transition-new()
pseudo-elements.
These two pseudo-elements target the screenshot before editing, and the screenshot after editing, respectively.
And of course, these selectors can be used to apply styles to both of these images.
A very simple example is to change the duration of the animations.
Note 1: The same properties must often be applied to both pseudo-elements to obtain a consistent result.
Note 2: The term root
means that these styles apply to the entire page during a transition, not just to certain elements.
::view-transition-old(root) {
animation-duration:2s;
}
::view-transition-new(root) {
animation-duration:2s;
}
But it's possible to do much more sophisticated things, such as defining new animations entirely.
Note: These codes are given to you in principle. They would work on a page with a single display transition, but on
this page has many of them, and they will have to be completed as we will see a little later.

@keyframes rotation-old {
from {transform:rotate(0deg); opacity:1;}
to {transform:rotate(360deg); opacity:0;}
}
@keyframes rotation-new {
from {transform:rotate(0deg); opacity:0;}
to {transform:rotate(360deg); opacity:1;}
}
::view-transition-old(root) {
animation:rotation-old 1s;
}
::view-transition-new(root) {
animation:rotation-new 1s;
}

@keyframes zoom-old {
from {transform:scale(1);}
to {transform:scale(0);}
}
@keyframes zoom-new {
from {transform:scale(0);}
to {transform:scale(1);}
}
::view-transition-old(root) {
animation:zoom-old 1s;
}
::view-transition-new(root) {
animation:zoom-new 1s;
}
Very often animations change the opacity
property because it is absolutely necessary that the image of the old screen disappears for
that the new screen appears. This is done by varying their opacity:
- Changing the opacity from
1
to0
on::view-transition-old()
, - Changing the opacity from
0
to1
on::view-transition-new()
.
The view-transition-name
property.
By default, animations are applied to the entire page (root
element). In the case of a fade transition, it's not a problem because
the elements that are not modified are replaced by themselves: nothing is seen.
But other animations cannot be applied to the root
element.
The view-transition-name
property allows you to isolate an element and apply animations to that element only, leaving the
the rest of the document outside the animation. This is done by associating an element with a transition identifier. This identifier is then found
in the parameter pseudo-elements ::view-transition-old()
and ::view-transition-new()
.
#logo {view-transition-name: demo-name;}
::view-transition-old(demo-name) {
...
}
::view-transition-new(demo-name) {
...
}

Here, the animation chosen is a rotation. By default, it applies to the entire page

The title and map have each been given a transition ID and different animations.
The :active-view-transition
pseudo class.
This pseudo class targets the root element (:root
) when a display transition is in progress. It no longer targets anything once the transition is complete.
In the example below, we used it to blur the page while the card flips.
This pseudo-class can of course be combined with another selector so as not to target the entire page.
:active-view-transition {filter:blur(5px);}
Multiple view transitions on the same page.
By default, all page transition effects are triggered at the same time. But it is often necessary to have several transition effects on the same page. To do this, it will be necessary to:
- Associate a transition name with each of the elements that are the object of a transition. This is the role of the
view-transition-name
property.
Without using theview-transition-name
property, the default name isroot
. - Identify the type of transition you want in the Javascript code, with the
types
parameter, and use the pseudo-class:active-view-transition-type()
in CSS code.script function turnCardVT(el) { document.startViewTransition({ update:() => turnCard(el), types:['demo-type'] }); } /script style :active-view-transition-type(demo-type)::view-transition-old(demo-name) { ... } :active-view-transition-type(demo-type)::view-transition-new(demo-name) { ... } /style
In summary, here's the code needed for this last example, and for it to work without interacting with the other view transitions set to this page.
/* The function is called by clicking on the card */
/* onclick="turnCardVT(this, 'fondu')" */
script id="tutorial1-js"
function turnCardVT(el,type) {
if (document.startViewTransition) {
document.startViewTransition({
update:() => turnCard(el),
types:[type]
});
}
else {
alert('Navigateur non compatible.');
}
}
function turnCard(el) {
if(el.src.indexOf('back')==-1) {
el.src='img/@view-transition-back.png';
}
else {
el.src='img/@view-transition-' + el.alt + '.png';
}
}
/script
style
@keyframes fondu-old{
from {filter:brightness(100%);}
to {filter:brightness(10%);}
}
@keyframes fondu-new{
from {filter:brightness(10%);}
to {filter:brightness(100%);}
}
#tutorial5 {view-transition-name:tutorial5;}
:root:active-view-transition-type(fondu)::view-transition-old(tutorial5) {
animation:fondu-old 1s;
}
:root:active-view-transition-type(fondu)::view-transition-new(tutorial5) {
animation:fondu-new 1s;
}
/style
Cross Document View Transition.
IIt is possible, using a comparable mechanism, to define a view transition when one page replaces another. That is to say, every time whether a user clicks on a link, uses the back button, or chooses a page from favorites.
The constraint is that these two pages must be on the same domain.
The basic solution is simple to implement: both pages must have the @view-transition
directive in their CSS code. Each of them must
also define the animation to run after the page loads.
If all pages are displayed to the same effect, it is common to write CSS styles in a separate file, with each page referencing this
file with a link tag in their header.
Here's an example of minimal code.
@view-transition {navigation: auto;}
@keyframes navigate-old {
from {transform:translate(0);}
to {transform:translate(100%);}
}
@keyframes navigate-new {
from {transform:translate(-100%);}
to {transform:translate(0px);}
}
::view-transition-old(root) {
animation:navigate-old 1s;
}
::view-transition-new(root) {
animation:navigate-new 1s;
}
The link below takes you to a page with this code. If you are using a compatible browser, this will give you an idea of the result: demo link.
In short.
- To enable a display transition, you need some Javascript, with the
startViewTransition()
function. - To customize the animation (by default a fade), see the pseudo-elements
::view-transition-old()
and::view-transition-new()
. - To not apply the animation to the entire page, see the
view-transition-name
property. - When multiple animations are defined on the same page, to ensure that they don't all fire at the same time,
See the pseudo-class
:active-view-transition-type()
. - To define a page-to-page display transition, see the
@view-transition
directive.
Browsers compatibility.
the @view-transition
directive to establish a transition between pages (Level 2 of the specification).transition
@view-transition
at-rule
Browsers on computers :
Mobile browsers :
Outdated or marginal browsers :

Internet Explorer

UC Browser pour Androïd

Opéra Mobile

QQ Browser

Baidu Browser

Opéra

Firefox pour Androïd

Firefox

Androïd Brower

Chrome pour Androïd

Samsung Internet

Safari

Safari sur IOS

Chrome

Edge

KaiOS Browser

Opéra mini
@view-transition
at rule historic.
-
CSS View Transitions Module Level 2
Level 2 of the specification introduces the possibility of defining view transitions between several documents, thanks to the new@view-transition
at-rule.May 16, 2024Working Draft.
See also, about view transitions.
The specification on view transitions (CSS View Transitions Module) is mostly rich in selectors (pseudo-elements and pseudo-classes).
Selectors:







Properties:
