D
P
0

CSS & Web Animation

View Transitions API Flashes and Animates on Every Back Button? The Opt-in Meta Hits Every Navigation

July 11, 2026·5 min read
View Transitions API Flashes and Animates on Every Back Button? The Opt-in Meta Hits Every Navigation

A while back I adopted the View Transitions API for cross-document navigation on a site I built. The idea was simple: turn on smooth transitions between pages so movement feels less abrupt, without writing an SPA. Just one opt-in meta tag and a bit of default CSS, they said. I deployed it, opened the site, and at a glance it looked slick.

Then I started clicking around like a real visitor would. And that is when it started to feel off. Every ordinary navigation triggered a faint flash, a kind of blink I never asked for. The worst was when I hit the browser Back button: a page that should have restored instantly instead animated in, flashed, and only then showed its content. It was most noticeable on the contact page, which was supposed to be the calmest, fastest page on the whole site.

The symptom

No console error. No broken layout. Everything "worked," but it felt wrong. Each time I moved between pages, there was a brief moment where the old page seemed to fade and the new one animated in. For a deliberate forward navigation, I could just about tolerate it even though it was not what I had designed. But for the Back button, it felt genuinely wrong.

The Back button is supposed to feel instant. A visitor presses it because they want to get back quickly to where they were, not watch an animation replay. Instead of a seamless restore, I got a full flash every single time. On the contact page the effect stood out most, because that page is lightweight and normally snaps back in an instant, so the unnecessary animation actually read like lag.

The investigation

My first instinct was to blame JavaScript. I checked whether I had written any navigation handler, whether some routing library was interfering. Nothing. The site is plain cross-document navigation, a full page each time, with no SPA router.

Then I started tracing what had changed between "the site feels normal" and "the site flashes constantly." The answer was one thing: I had just turned on View Transitions. I reopened what I had added. There was an opt-in meta tag I injected through functions.php in this WordPress theme:

<meta name="view-transition" content="same-origin">

And accompanying that meta, about a hundred lines of default transition CSS I had pasted into style.css, full of keyframes and ::view-transition-old and ::view-transition-new selectors for fades and slides.

The moment I saw those two pieces side by side, the puzzle started to come apart. That opt-in meta tag is not selective. It tells the browser: enable a cross-document view transition for every same-origin navigation. Every navigation. Including back-forward restores.

The root cause

What I had misread: the view-transition meta tag is not a "turn on transitions where I want them" switch. It is a "turn on transitions for everything" switch. Once present, it blankets a cross-document transition over every same-origin navigation, and my hundred lines of default CSS supplied the animation. The browser dutifully ran that animation everywhere, including when restoring a page from bfcache via the Back button.

That is where the wrongness lived. Back-forward restores are supposed to be fast and undramatic. But because the opt-in was blanket and the CSS was not scoped to any particular navigation, every Back triggered the full animation. Not a browser bug. Not a JavaScript conflict. Purely me leaving a blanket default switched on, then wondering why the effect showed up in places I never wanted it.

What made this easy to miss: on a deliberate forward navigation, the animation looked "intentional," so I did not suspect it. It was only touching the Back button, where visitors hold a strong expectation about speed, that the same effect immediately read like a defect.

The fix

I paused and asked myself: is this feature actually needed? The answer was no. The transition was purely cosmetic, not part of the design I had drawn up, and nothing in the requirements asked for it. So I did not go engineer the CSS to exclude the Back button. I pulled the feature.

First, remove the opt-in meta tag from functions.php, the snippet that injects this:

<meta name="view-transition" content="same-origin">

Second, delete the entire associated transition CSS from style.css, about a hundred lines of keyframes and ::view-transition selectors:

::view-transition-old(root),
::view-transition-new(root) {
  animation-duration: 0.3s;
}

Once both were gone, the flash vanished immediately. Ordinary navigation went back to plain, instant page changes, and the Back button restored the contact page instantly with no animation at all. Exactly as it was before I touched anything.

Checklist for cross-document View Transitions

  • Realize the view-transition meta is blanket: once you opt in, it hits every same-origin navigation, including back-forward restores from bfcache.
  • If the Back button feels slow or flashes after adopting View Transitions, suspect the blanket opt-in plus default CSS first, not your JavaScript.
  • Adopt cross-document transitions deliberately and scoped: limit them to the navigations you actually want, do not leave a blanket default running everywhere.
  • If the transition is purely cosmetic and not required by the design, ripping it out is a legitimate fix, not a surrender.

The takeaway

The View Transitions API is tempting because it is cheap to add: one meta tag, a little CSS, and it looks modern instantly. But its opt-in meta is not polite about scope. It enables transitions for every same-origin navigation, and that includes the exact moment a visitor least wants to wait: pressing the Back button. Since then I treat navigation animation features like a contract, not a free garnish. If I do want a transition, I scope it deliberately. If I do not truly need it, I do not switch it on at all.