Description
Hello 🙂
I started using Turn with the view transition API and I noticed a few things that could maybe be integrated into the library, let me know what you think (I am still learning how the API works and its best practices, but I think I have a pretty good understanding of it already).
1. Add an attribute helper to add view-transition-name
on elements during transitions
I think one of the best features of the view transition API is the ability to let the browser automatically translate elements from one place to another using view-transition-name
. From what I understand (and what I've tested so far), it's important to have this attribute added only during the transition and then removed if the DOM elements are not the same (which will be the case 99% of the time during visits). This is explained here.
With that, I think it's in the scope of this library to add an attribute like data-turn-transition-name
that would only get added to its respective element during a view transition, and then automatically removed (by setting the view-transition-name
property to an empty string or none
).
It would also maybe be interesting to have it "scoped" to its current element, so it does not add the view-transition-name
property on every element on the page? I don't know what the best practises for names are. e.g. I have a list of products, do I just add view-transition-name: product-title;
to the product I clicked on during the transition, or add view-transition-name: product-title-1;
, etc... On each product currently visible on my page?
I did a quick implementation with the current events dispatched by Turn, I have no idea if this is the best way to do it and it could probably get some improvement, but it worked pretty well during my testing.
let pendingTransitions: HTMLElement[] = [];
// Add transition name to elements with data-turn-transition-name attribute (only those inside the initiator)
window.addEventListener('turn:before-transition', (({ detail }: CustomEvent<{ initiator: HTMLElement }>) => {
if (getPrefersReducedMotion()) {
return;
}
const { initiator } = detail;
const transitions = initiator.querySelectorAll('[data-turn-transition-name]');
transitions.forEach((transition) => {
if (!(transition instanceof HTMLElement)) {
return;
}
// @ts-expect-error Experimental API
transition.style.viewTransitionName = transition.dataset.turnTransitionName;
pendingTransitions.push(transition);
});
}) as EventListener);
// Remove the transition names we added before
window.addEventListener('turn:before-enter', (() => {
pendingTransitions.forEach((transition) => {
// @ts-expect-error Experimental API
transition.style.viewTransitionName = 'none';
});
pendingTransitions = [];
})
6346
as EventListener);
With that, my details page would have the transition names set
<h1 style="view-transition-name: news-title;">Some news</h1>
<p style="view-transition-name: news-desc;">News description<p>
And my results on my search page would have the data-
attribute with the same name
<a href="news/some-news" class="news__result">
<p data-turn-transition-name="news-title">Some news</p>
<p data-turn-transition-name="news-desc">News desc...</p>
</a>
The title and description now nicely translate when clicking on the link or going back to the search page.
2. Allow hybrid configuration for Firefox/Safari
I found myself in a situation where I had to make a choice : either support only view transition browsers and hope Firefox/Safari implement it soon enough, or give up on it and use data-turn-enter
& data-turn-exit
only.
This happened because on a page with a navbar header, a footer and a sidebar (lots of navigation), I wanted these elements to not animate during a visit, so I would add data-turn-enter
& data-turn-exit
to the container with the current view. It works well but breaks the view transition API completely. It seems that as soon as I add these attributes, the view transitions are not taken into account at all (most likely because they conflict with each other as Turn is animating the whole view with a fade). It would be interesting to be able to add these attributes, but only use them if the view transition API is not available.
I know what I want to achieve would most likely be achievable by using CSS only rather than the data-
attributes, but it would require more work than simply adding my Tailwind animation to the attribute.