Different Page Transitions For Different Circumstances
Different Page Transitions For Different Circumstances êŽë š
I feel like common usage for multi-page view transitions is to set up a general system for them that applies generally to all pages and elements, then let it ride.
But I just recently saw the DOM events in JavaScript and how they can be used to set a âtypeâ. So check out the events first:
// The old / unloading page
window.addEventListener('pageswap', async (e) => {
if (e.viewTransition) {
}
}
// the new / loading page
window.addEventListener('pagereveal', async (e) => {
if (e.viewTransition) {
}
}
You can do anything you might want in there, but an especially interesting thing to me is that you can set the view transition type, and do so conditionally.
Customize the View Transition Type for One Particular URL
Just to clearly illustrate the point, say you want one particular page to have a different transition animation than all the rest of them. Says itâs the âShowsâ page on a website at the relative URL /shows. Then weâd watch for the pagereveal event and test that URL and if itâs a match weâll set the type:
window.addEventListener("pagereveal", async (e) => {
if (
e.viewTransition &&
document.location.pathname === "/shows"
) {
e.viewTransition.types.add("toShowsPage");
}
});
That toShowsPage is just an arbitrary name weâre making up to use in CSS to customize the animation when itâs set.
The âDefaultâ View Transition
Weâve got a custom type being set, but letâs set up the default first. Something like this is neat:
::view-transition-old(main) {
animation-name: slide-out-to-left;
animation-duration: 1s;
}
::view-transition-new(main) {
animation-name: slide-in-from-right;
animation-duration: 1s;
}
@keyframes slide-out-to-left {
to {
translate: -150px 0;
opacity: 0;
scale: 0.5;
}
}
@keyframes slide-in-from-right {
from {
translate: 100vi 0;
}
}
In my example here, it assumes a <main> content area with view-transition-name: main; so that is the element being targeted specifically here. Now when I move pages (by just clicking regular olâ links) I get this effect:
Using the Custom Type for a Custom Animation
When the âShowsâ link is clicked and the /shows page is loaded, weâre setting the toShowsPage type, and this is the magic moment we can use it in CSS:
html:active-view-transition-type(toShowsPage) {
&::view-transition-new(main) {
animation: to-shows-page 1s forwards;
}
}
@keyframes to-shows-page {
from {
scale: 1.1;
translate: 0 -200px;
}
}
Because of the extra specificity over just ::view-transition-new, this gives us an opportunity to override the default animation here with a new set of keyframes. Now just the Shows page will come down from the top instead. See the difference:
Notes
I think itâs cool we have this level of control and interplay between JavaScript and CSS.
I first saw this in Bramusâ Cross-document view transitions for multi-page applications, which is a good resource and covers âforwardsâ, âbackwardsâ, and âreloadâ view transition types which seems extremely practical and makes me wish were something we have native CSS access to detect.
There is a native CSS way to declare the types, but Iâm not quite understanding why that is useful or important to do. All I understand so far is that any type that isnât listed there when you do declare them invalidates them, so maybe thatâs useful somehow?
I would have thought the âtypesâ stuff would have been a bit newer, and thus lower browser support, than other view transitions stuff, but thatâs wrong. MDN has JavaScript type setting as well as CSS :active-view-transition-type() as the same level of browser support as multi-page view transitions in general, that is to say, Chrome, Safari, and flagged in Firefox.