Back to the Blog
Essay

How to Add CSS Page Transitions in Webflow (Load + Exit)

Add smooth CSS page transitions in Webflow using native Page Load and link-click exit animations, plus the honest limits of when you actually need Barba.js or Swup.

By Social Catnip
Jun 18, 202611 min read

How to Add CSS Page Transitions in Webflow (Load + Exit Animations)

Short version: to add CSS page transitions in Webflow, you build two halves in Interactions → Page Trigger. A Page Load animation fades or slides your content in when the page arrives. A Page Exit animation, triggered on link clicks, fades the old page out before the browser navigates away. Under the hood Webflow is writing CSS transform and opacity keyframes for you. That's the whole trick — and it covers about 90% of what people actually mean when they ask for "smooth page transitions."

The other 10% is the honest part nobody leads with: Webflow ships a full page on every navigation. It isn't a single-page app. So a true persistent transition — the kind where a hero image flies across the screen and morphs into the next page — needs JavaScript like Barba.js or Swup, and that comes with real SEO and performance tradeoffs. I'll show you both, and tell you which one I'd actually reach for.

I've been building on Webflow for seven years. Long enough to have shipped the slick version, the over-engineered version, and the version a client's bounce rate quietly thanked me for. Let's do it right.

Table of Contents

<h2 id="how-they-work">How CSS page transitions actually work</h2>

Strip away the Webflow UI and a page transition is two CSS properties doing almost all the labor: opacity and transform. Those two are the only properties the browser can animate cheaply, on the GPU, without forcing a layout recalculation on every frame. Animate width, top, or margin instead and you've handed the main thread homework 60 times a second. Stick to opacity and transform and it stays buttery.

A bare-bones CSS version of a page-load fade looks like this:

@keyframes pageIn {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: translateY(0); }
}

body {
  animation: pageIn 0.4s ease-out both;
}

That's it. The content starts slightly down and transparent, then settles into place over 400 milliseconds. When you build a Page Load interaction in Webflow, you're drawing that exact same keyframe in a visual timeline — Webflow just generates the CSS and the bit of JS that fires it. You don't have to hand-write it. But knowing what's underneath is what keeps you out of trouble later, when the timeline does something weird and you need to know why.

One number to tattoo on your wrist: keep it under ~500ms. Anything slower stops reading as "smooth" and starts reading as "slow site." A transition is seasoning, not the meal.

<h2 id="page-load">Step 1: Build a Page Load animation in Webflow</h2>

This is the easy, safe, no-JavaScript-baggage half. Here's the click path:

  1. Open the Interactions panel (the little stopwatch icon in the right toolbar).
  2. Under Page Trigger, click the plus next to Page Load and choose Start an animation.
  3. Hit Create TimelineNew Timeline.
  4. Select the element you want to animate — usually your main page wrapper or the body.
  5. Add an Opacity action: set the initial state to 0% and the animated state to 100%.
  6. Add a Move action: initial state Y: 16px, animated state Y: 0px.
  7. Set the duration to around 0.4s and easing to Ease Out.

The one gotcha that trips everyone up: set the initial state. In the timeline, Webflow lets you define a "before page load" state — the value the element holds before the animation runs. If you skip it, the page renders fully visible for a split second, then jumps to opacity 0 and fades back in. It looks like a flicker, or a bug, because it is one. Set the initial state to 0% opacity and the flash disappears.

Test it on mobile too. A Move action that feels gentle on a 27-inch monitor can feel like the whole page is sliding off a phone. We ship every animation responsive on the first build, not as a follow-up — and page transitions are exactly the kind of thing that looks great on desktop and queasy on a thumb-scrolled phone if you don't check.

<h2 id="page-exit">Step 2: Add a Page Exit (link-click) animation</h2>

Here's where it gets clever, and where Webflow's lack of an SPA architecture forces a small workaround.

You can't truly animate out of a Webflow page, because the moment a link is clicked the browser is already fetching the next document. There's no native "wait, finish my animation first" hook. So the standard pattern is a fade-out overlay that runs on click, timed just long enough to mask the hard navigation:

  1. Create a full-screen div (call it page-cover), fixed position, covering the viewport, set to display: none and 0% opacity at rest.
  2. Build a Mouse Click (Tap) interaction on your nav links: on click, set page-cover to display block, then animate its opacity 0% → 100% over ~0.3s.
  3. Add a small JavaScript delay before navigation so the fade has time to finish. A few lines in an Embed:
<script>
document.querySelectorAll('a[href]:not([href^="#"])').forEach(function (link) {
  link.addEventListener('click', function (e) {
    if (link.hostname !== window.location.hostname) return; // skip external links
    e.preventDefault();
    document.body.classList.add('is-leaving'); // CSS fades a cover in
    setTimeout(function () { window.location = link.href; }, 300);
  });
});
</script>
.page-cover { position: fixed; inset: 0; background: #0b0b0b;
  opacity: 0; pointer-events: none; transition: opacity 0.3s ease; }
.is-leaving .page-cover { opacity: 1; }

Pair that 300ms exit with your 400ms Page Load fade-in and you get a continuous dip-to-color-and-back across the navigation. It feels like a single smooth transition even though the browser hard-loaded a brand-new page in the middle. Smoke and mirrors, but the good kind.

The catch to respect: that e.preventDefault() means you now own navigation. Test it against middle-clicks, cmd/ctrl-clicks (people open things in new tabs), and your back button. Break the back button and you've made the site worse in the name of pretty. Pretty. Pointless.

<h2 id="the-limit">The honest limit: Webflow isn't an SPA</h2>

Time for the part the slick YouTube tutorials skip. Webflow has real limits, and pretending otherwise is how sites collapse.

Every time you navigate a Webflow site, the browser throws away the current page and loads a fresh HTML document. Full stop. That's a multi-page application — same as a plain static site. The cover-fade trick above doesn't change that; it just hides the seam with a well-timed curtain.

A true persistent transition — where a thumbnail grows into the next page's hero, or the header stays put while the content morphs underneath it — requires the old page and the new page to coexist for a moment in the same DOM. Webflow can't do that natively, because it never holds two pages at once. To get there you have to bolt on a JavaScript router that intercepts the click, fetches the next page's HTML in the background, swaps the content in place, and runs your animation between the two states. Which brings us to the tools people reach for.

<h2 id="barba-swup">When to reach for Barba.js or Swup (and the catch)</h2>

Barba.js and Swup are the two go-to libraries for real page transitions on otherwise-static sites. They both do the same core job: catch link clicks, AJAX-fetch the next page, swap the <main> content, and give you lifecycle hooks (leave, enter) to animate the handoff. The result is genuinely slick — that fluid, app-like glide between pages.

Here's the catch I tell every client who asks for it, in plain English: you are now maintaining a custom routing layer on top of a no-code platform. That's three real costs:

  • SEO risk. Google renders JavaScript, but a content swap that mis-fires — a missed history push, a script that doesn't re-init on the new page — can leave crawlers seeing the wrong title, or the same one on every URL. The platform that's supposed to make Webflow easy now needs a developer babysitting it.
  • Re-initialization tax. Every Webflow Interaction, every embedded script, every third-party widget has to be torn down and re-bound on each page swap, or your animations silently stop working after the first navigation. This is the bug that eats an afternoon.
  • The junk-drawer trajectory. It starts clean. Then someone adds a campaign page the router doesn't know about, then a CMS template the swap logic doesn't account for, and six months later one new page is a two-week ordeal involving three Slack threads and a prayer. The transition library became a tax.

My honest take after seven years: for 90% of marketing sites, the Page Load + cover-fade combo from Steps 1 and 2 is the right answer. It's native, it's fast, it survives a redesign, and no developer has to babysit it. Reach for Barba or Swup only when the brand experience genuinely lives or dies on that motion — a portfolio, an agency site, a launch page where the animation is the product. For a SaaS site whose job is to get a demo booked, it's usually decoration with a maintenance bill attached. Design that wins awards can lose customers; one clear action per page beats a gorgeous transition that hides the button.

If you do go that route, do it with eyes open — and ideally with someone who's wired it before. That's the kind of build our Webflow development agency gets called in to do (and, just as often, to un-do).

<h2 id="core-web-vitals">Don't let the animation tank your Core Web Vitals</h2>

A transition that delays your content from showing up is a transition that hurts your rankings. Google's Core Web Vitals — specifically Largest Contentful Paint and the newer Interaction to Next Paint — measure exactly the moments a clumsy page animation can wreck.

Three rules I hold to:

  • Never fade in your LCP element from opacity 0 with a long delay. If your hero image is the largest thing on screen and it spends 600ms invisible, you just told Google your page is slow. Animate a wrapper, not the hero, or keep the hero's fade tight and immediate.
  • Animate only transform and opacity. Repeat offender: animating height, top, or margin causes layout thrash and can spike your Cumulative Layout Shift. The GPU-friendly two are the only ones worth using.
  • Respect prefers-reduced-motion. Some users get motion sickness from page slides. A two-line media query that disables the animation for them is both an accessibility win and a quiet SEO signal. Webflow exposes this in the Interactions settings now — use it.

We hand off Webflow builds at a 99/100 average Lighthouse score, and page transitions are one of the first places a careless build leaks points. If you've already got transitions in place and your scores are sliding, that's a diagnosable problem — we walk through the usual culprits in diagnosing and resolving Webflow performance issues. Fast and pretty aren't enemies. You just have to know which properties to animate.

<h2 id="faq">FAQ</h2>

How do you add page transitions in CSS? Define a @keyframes animation that changes opacity and transform, then apply it to the page wrapper or body with the animation property — for example animation: pageIn 0.4s ease-out both. For the exit half, use a CSS transition on a fixed-position overlay that fades in on link click, with a short JavaScript delay before navigation. In Webflow, the Interactions panel builds these same keyframes for you visually.

Can Webflow do true page transitions without code? Partly. Webflow's native Page Load animations and link-click interactions get you a smooth fade-in and a masked fade-out with no custom code. But a true persistent transition (content morphing across pages) needs a JavaScript library like Barba.js or Swup, because Webflow loads a fresh document on every navigation and never holds two pages at once.

Do page transitions hurt SEO? The native Webflow approach is safe — it's standard CSS and doesn't change how pages are crawled. JavaScript-driven transitions (Barba/Swup) can hurt SEO if the content swap mis-fires and crawlers see the wrong title or duplicated metadata. They also risk Core Web Vitals if you fade in your LCP element with a long delay. Done carefully, either approach is fine; done carelessly, the JS route is the riskier one.

How long should a page transition be? Keep it under about 500 milliseconds, and ideally closer to 300–400ms. Faster than ~200ms and the effect is invisible; slower than ~500ms and it starts reading as a slow site rather than a smooth one. A transition is seasoning — you can't put it on everything.

What's the difference between a page transition and a page animation? A page animation (Page Load) runs when a single page arrives — it animates content into view. A page transition covers the handoff between two pages — the exit of the old page and the entrance of the new one stitched together so navigation feels continuous. In a multi-page tool like Webflow, you build a transition by pairing a load animation with a link-click exit animation.


Page transitions are one of those features that's worth doing well and not worth overbuilding. Get the native fade-in and cover-fade right, keep it under half a second, animate only the cheap properties, and 90% of sites are done. If your build genuinely needs the app-like version — or you've already got one that's quietly bleeding Lighthouse points — that's the kind of thing our Webflow development agency untangles for a living. Tell us what you're after and we'll point you at the simplest version that actually works.

Want this for your team?

Send us a brief and we'll come back with a fixed-price plan in 48 hours.