BarbaJS Page Transitions
What it does
A three-page editorial site whose routes swap behind a curtain: click a nav link and two sheets — an accent one leading a solid ink panel that carries the name of the page you are travelling to — ride up over the content area, the route is replaced behind them, and they keep going off the top while the new heading lifts out of its mask and the rows step in. The masthead stays put the whole time, so the swap reads as navigation and not as a loose animation. GSAP timelines (power4.inOut curtain, power3.inOut masked heading) reproducing Barba.js's sync lifecycle with a queued in-page router.
How it's built
| Category | transition |
|---|---|
| Tech | gsap |
| Complexity | page |
| Performance cost | light |
| Mobile-safe | yes |
How it works
A small three-page editorial site where changing page is the show. Click a link in the masthead and two sheets rise from the bottom of the content area, a thin blue sheet racing just ahead of a dark ink panel. For a moment the page is covered, and the panel names where you are going, its number and its title. Then both sheets keep travelling up and off the top, uncovering the new page: its giant heading lifts out of a mask and the rows of content step up behind it.
The motion is GSAP with no plugins. The navigation reproduces how Barba.js handles a synchronous transition, where the old and new pages overlap, with a small hand-written router instead of the library.
How the transition is built
Everything hangs off one GSAP timeline per navigation. The curtain moves in one continuous direction, up to cover and up again to uncover, with a short hold between the two moves. A label marks the instant the stage is fully covered, and every other event is placed relative to that label: the old page is removed behind the closed curtain, the new one is made visible, and its reveal starts slightly later so that it overlaps the curtain leaving.
The incoming page is added to the DOM next to the outgoing one before the curtain closes, but kept invisible. During the cover both exist at once, which is the overlap that makes the swap seamless. The reveal of each page is scoped to that page's own container, so the outgoing heading never animates by accident while both are present.
The heading reveal is a simple mask: the heading sits inside a window that clips it and travels up from below its own edge.
Where it gets hard
The most common failure is invisible. The sheets are parked below the stage in CSS so the first paint is never covered, but GSAP cannot read a percentage back from the browser, so a timeline that trusts the CSS alone ends up animating from the wrong value and the curtain simply never moves. The rest position has to be stated again in GSAP's own terms and restored in the same terms after every transition.
The second is impatience. A visitor who clicks twice during a transition must not break it. The router remembers the latest destination and plays it as soon as the current transition ends, so the highlighted link and the visible page always agree, and clicking the page you are already heading to does nothing.
Performance, mobile and accessibility
Only transforms and opacity are animated, so it runs smoothly on phones. The first page is real HTML, so it is readable before any script runs. With reduced motion enabled there is no curtain at all: the page changes immediately, because a faster animation would still be the movement that the setting asks to avoid.
Rebuild it with AI
This component's prompt is part of the paid library. Below you can read how it starts; the full prompt, the exact structure, timing and easing an AI agent needs to rebuild the effect, unlocks with any paid plan, yearly or lifetime.
# BarbaJS Page Transitions — Two-Sheet Curtain Wipe + Masked Heading Reveal Between Routes
## Goal
Build a small **three-page editorial site** — a fictional press called **Recto** — where the pages are swapped in place, and make the swap the star of the page. A fixed masthead holds the brand and three real nav links (**Index / Studio / Contact**). Clicking one fires the transition: a **blue accent sheet leads a solid ink panel** up from the bottom of the content stage, both travelling in one direction; while the stage is covered the route is replaced underneath; the two sheets keep going **off the top**, uncovering the new page, whose giant `<h1>` **lifts out of a mask** and whose rows **step up** behind it. The ink panel carries the **name and number of the page you are travelling to**, so even a frame grabbed mid-wipe reads as "we are on our way to Studio" rather than as a coloured rectangle.
The whole thing reproduces Barba.js's `sync: true` lifecycle (leave + enter overlap, the outgoing container is dropped mid-transition) with a hand-rolled in-page router — no real multi-page fetch, no framework.
**Three things make this legible, and all three are design decisions, not decoration:**
1. **The masthead never moves.** The curtain covers the content stage only, not the whole viewport. You watch the nav highlight jump to the link you clicked while the page area is being replaced — which is what tells the viewer this is *navigation*, not a loose animation.
2. **Each route has genuinely different content and a different layout** — a numbered work list, a two-column studio statement with a facts table, a huge mail address with a channel grid. If all three routes were the same big word on an empty field, nothing would read as a page change.
3. **The first paint is the first page.** The sheets park *below* the stage and the first route is authored in the HTML, so the very first frame is the Index page, never a full-bleed panel.
## Tech
Vanilla HTML/CSS/JS with ES module imports, in a fresh Vite project. Install and import from npm:
- **`gsap`** (3.x) only. **No GSAP plugins, no ScrollTrigger, no SplitText, no Lenis, no Three.js.**
```js
…
Premium prompt
Unlock this prompt, and every other one
From $99/year, or $139 once for lifetime access. Commercial license included.
See pricing Or start with the free set Already bought? Sign in
Learn the technique
New components in your inbox
One email a week, only when new components ship, each with its live demo and prompt.