← Blog

Building a Scroll-Driven Website: A Case Study

Illustration on a blue-to-tan gradient: five white cards fanned like a deck of slides, labeled with this site's real page URLs — home, /web-development/, /portfolio/, /blog/, /contact/ — with a downward arrow beside them, captioned "Five real pages. One continuous scroll."

Every post on this blog so far has explained a piece of this site — what scrolljacking is, how to make it accessible, whether it hurts SEO, the API that animates it. This one is the whole story in order: what I set out to build, the rules I made myself follow, what broke, and what shipped. Consider it the case study for the site you’re currently scrolling.

The brief

I had a WordPress agency site, and I was done with it — done with the plugin treadmill, done with pages I didn’t fully own. The replacement had one job beyond replacing it: the site itself had to be the pitch. I sell a way of building websites; the only honest portfolio for that is a site built that way, where anything I claim on a page is being demonstrated by the page. Which meant no safe, ordinary rebuild. It had to do something you don’t see every day, without breaking any of the things ordinary sites do right.

The spark

The motion came from CodePen — a one-page navigation demo by hrtzt where the whole screen slides sideways, one panel per input, with a little overshoot as each panel’s content lands. It’s the kind of motion that makes you grin. It’s also, structurally, a single page — and a single page was exactly what I couldn’t ship. So the real project became: keep that exact feel, but spread it across a real, multi-page website. Original code, borrowed soul.

The architecture: a deck of real pages

The concept I landed on is a deck. Every section of every page is exactly one screen tall. Window scrolling is switched off; the wheel, the arrow keys, and touch swipes each advance exactly one section, animated by the browser’s View Transitions API. So far, standard scrolljacking.

The trick is at the edges. Scroll past the last section of a page and the site doesn’t stop — it navigates, a real page load to the next URL in the chain, and a cross-document view transition plays the same slide animation across the boundary. Same keyframes, same easing, same duration. You can’t see the seam, and that’s the whole point: the visitor experiences one continuous deck, while Google — and your back button, and your bookmarks — see five ordinary pages. The one sneaky bit is a direction flag passed between pages, stamped before the first paint, so the incoming page knows whether to slide forward or backward. The rest is CSS.

The rules

Before writing it, I wrote rules, because scrolljacking has a deserved reputation and each rule answers one of the ways it usually goes wrong. Every screen gets a real URL. Every word lives in the HTML before any script runs. Keyboard input works everywhere the wheel does. And if your system asks for reduced motion, the whole deck stands down and the site becomes a normal, scrolling website — the full surrender, not a toned-down animation. No frameworks, no libraries: one CSS file, two small scripts, hand-written from a blank file.

What broke

A case study that skips this section is an ad, so: things broke. The one that earned a permanent rule I now check on every build is the white flash. The site’s glass-look buttons are translucent layers that read dark because of what’s behind them — and when the View Transitions API snapshots an element, the snapshot has no behind. Rendered alone, the glass is suddenly white, and for a split second every page change strobed. It regressed three separate times before the fix became law: the page background lives on the root element, and glass never gets its own snapshot without a dark base baked in.

The blog nearly broke the concept itself. A deck wants every section one screen tall; a blog index wants to grow forever. The answer was a hybrid: a deck section that scrolls inside itself, holding the deck in place until you’ve reached its edge, then handing the scroll back. That one mechanism is why the blog you came from can sit inside the deck while the post you’re reading is a plain, normally-scrolling page. Old-fashioned reading didn’t need reinventing.

What shipped

Five deck pages in a chain, a blog hanging off the side, zero JavaScript libraries, one CSS file, and motion that survives every input method I can throw at it. The architecture became a template, the template became themes I sell, and this post is me eating my own cooking one more time: a scroll-driven website, documented on itself.

The deeper technical walkthrough lives on the web development page, which is itself five slides of the deck. And if you want a site that works like this — or looks nothing like this but is built with the same care — the contact page is one scroll past the blog. You could walk there from here.

Adam Hoidahl, The Better Website Guy

Designer/developer behind The Better Website. Hand-codes every build himself — no CMS, no templates, no page builders. See his CodePen.

Let's chat

← Back to the blog