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.

Strangely, I can trigger the alert while the transition is in progress on Safari Mobile. Is this blocking behaviour Chrome-only?
Hi Kevin, the text is misleading. The codepen does not show the normal behaviour where clicks are blocked, but already the solution, without the ::view-transition-group(root) and a ::view-transition pseudo that lets the clicks go through.
Sorry, my fault, I made this confusing. I had the demo in there in the “fixed” state, but I wanted it there demonstrating the actual problem. The Pen is now in the problem state, you can see the button-clicking behavior being broken.
Great article! Regarding your point about the snapshotted elements soaking up clicks while the View Transition is running, there is an important distinction between the named elements in the original DOM and the pseudo elements that the View Transition API shows during the transition.
The named elements (the ones with view-transition-name set) are not rendered at all while the View Transition is running. So there are no actual elements there to click. The API generated pseudo elements take their place, but you cannot attach event listeners to them because they are pseudo elements.
I assume the fact that the pseudo elements do not forward clicks to their named elements is actually a deliberate design decision. It would be hard to explain to users what they actually clicked when their pointer hits a flying, morphing pseudo element.