Just a little Public Service Announcement here.
Let’s say you’re doing a View Transition in the form of using the .startViewTransition() method. Maybe you’re showing an image bigger or sorting a table or moving some list items around or something.
If you don’t deal with it specifically, it’s likely you’re blocking interactivity on the rest of the page.
Here’s a very basic demo. There is an alert() button you can click to see an alert. Click that and see. Then run the View Transition and try to click that button.
See how you can’t click the alert button while the View Transition is running?
Because of the long 10s duration in that example, it should give you enough time to open DevTools and take a peek. You should be able to see the View Transition Pseudo Tree there. And if you hover over the top one, the ::view-transition, you’ll see it cover the entire viewport in light blue, telling you the dimensions of it cover the entire viewport.

So now you’ve got this big, giant, invisible element covering the entire viewport for the entire length of the transition. That’s what stops the interactivity, like clicking.
The Solution
Two-parter here.
One, the :root element has a view-transition-name by default, so it’s going to take part in the overall View Transition even if it doesn’t really do anything. I think this is a default so that entire pages can cross-fade in multi-page View Transitions. But we don’t need that. So if we remove the name, it won’t be one of the snap-shotted elements taking up space.
Two, the ::view-transition element is also that big giant viewport-covering element, and what we need to do there is make sure you can click through it.
:root {
view-transition-name: none;
}
::view-transition {
pointer-events: none;
}Code language: CSS (css)
The snap-shotted (for lack of a better term) elements you actually see transitioning on a page are essentially on the “top layer” while the View Transition is happening. So they’ll soak up clicks while they are there. Not sure why that’s the default, but that’s what we got.
Another Newer Solution
Another solution here is the “scope down” the View Transition. We don’t have to call document.startViewTransition() (like, on the document) although that definitely has the best browser support. Instead, we can call that method on the element that has the elements inside it that we care to transition. Like…
const parent = document.querySelector("#parent");
move.addEventListener("click", () => {
parent.startViewTransition(() => {
thing.classList.toggle("moved");
})
});Code language: JavaScript (javascript)
Scoped view transitions are just a good idea, allowing for things like keeping elements in a hidden overflow area and such (because the pseudo-element tree stays within that parent element). We also benefit here as, without doing any other CSS manipulation, interactive elements aren’t affected. You still might wanna do the CSS stuff, though, if you want to retain interactivity within the scoped area.
