I'm Pascal a Digital Designer from Switzerland, currently shaping digital experiences at Eyekon AG.

Project One

The card is pinned by CSS sticky positioning, so it stays exactly where it is while this text scrolls underneath the rounded corners. Nothing in here moves by transform, and the corners stay clipped the whole way through.

Page scrolling is intercepted while this card is the active one. Wheel and touch input are redirected into this container until the content reaches its bottom edge, at which point the page takes over again.

Because the container is a real overflow scroller, the scroll position is genuine. It can be read, set and restored, and the keyboard can drive it once the container has focus, which a transform based fake scroll can never offer.

Scrolling back upward behaves symmetrically. Once this content has returned to the top, the lock releases in the upward direction and the page moves again, revealing whatever sat behind this card.

The margin around the card stays constant at thirty two pixels through the entire pinned phase, because the padding lives on the sticky layer rather than on the card itself. That is what keeps the floating look stable.

The layer underneath is still pinned while this one covers it. It is scaled down slightly and faded, which is what gives the stack its sense of depth rather than a flat cut between sections.

Trackpad momentum is handled by normalising the wheel delta before it is applied. Browsers report deltas in pixels, lines or pages depending on the device, and treating a line delta as pixels would make this crawl.

When this last paragraph is reached the lock releases downward, the page resumes, and the next card rises to cover this one. Replace all of this placeholder copy with real project content once the mechanism feels right.

The point of a real overflow container is that the browser owns the scroll position rather than a script pretending to. That means the value is readable at any moment, it survives a resize, it can be restored after a reload, and assistive technology understands that this region scrolls. A transform driven equivalent looks the same in a screen recording and behaves quite differently in practice, because nothing in the accessibility tree ever learns that the content moved.

Because the lock routes deltas by hand, the release at either edge is exact rather than approximate. As long as the container still has room in the direction being scrolled, the whole delta is absorbed here. The moment the room runs out, whatever is left over is handed to the page in the same frame, so there is no visible stall between finishing this text and the next card beginning to rise.

Native scroll chaining would have looked simpler in the code and worse on the screen. Browsers latch a gesture to whichever element it began on, so a single firm flick that started on the page would carry straight past a pinned card without ever touching its contents. Routing the delta manually is the only way to guarantee the card actually holds the scroll once it has settled.

Wheel deltas are normalised before anything is applied. Most devices report pixels, but a mouse wheel in Firefox commonly reports lines and some configurations report whole pages. Multiplying a line delta as though it were pixels would make this text crawl at roughly a sixteenth of the expected speed, which is the sort of bug that only shows up on somebody else machine.

Touch input runs through the same routing function as the wheel, using the vertical distance between successive touch points. Multi touch gestures are deliberately ignored so pinch to zoom still behaves. The trade off is that intercepting touchmove suppresses the platform inertia, so a flick on a phone moves this content one to one with the finger instead of coasting.

The listeners exist only while this card is the active one. They are bound when the card finishes pinning and torn down the instant the next layer begins to rise, which is what stops two cards from both claiming the same gesture during the handoff. Nothing stays attached to the window once you have scrolled past this section.

Scrolling upward is handled symmetrically rather than as a special case. The same routing logic asks how much room exists above the current position, absorbs that much, and passes the remainder to the page. Returning to the top of this card therefore hands control back smoothly and lets the page travel back toward the hero.

Everything is measured from the live layout rather than assumed from the values on the canvas. The spacers report where each layer begins and ends, the viewport height comes from the browser, and the whole set is recomputed on the next animation frame whenever the page reflows. Resize the window at any point and the active windows stay correct.

Scroll position is deliberately not reset when a card goes inactive. If you scroll down past this card and then come back up, the content is still where you left it, and scrolling up will walk back through it before the page takes over again. Resetting to the top would feel like the card forgot what you were reading.

Setting the container to hidden rather than clipped while inactive is what makes that possible. A hidden overflow is still a scroll container, so the position survives untouched, but it no longer responds to user input. A clipped overflow is not a scroll container at all and would discard the position entirely.

The card only becomes scrollable once it has settled, which is what keeps the first part of the sequence behaving normally. While the card is still rising in from the bottom of the viewport it swallows nothing, so ordinary page scrolling carries it into place exactly as it did before any of this existed.

Every measurement is taken on an animation frame rather than synchronously, so a reflow triggered by one card does not force a layout read in the middle of another. The observer watches the document body, which catches font loading, image decoding and any late content change without needing to know what caused it.

There is no persistent state shared between the two cards. Each one derives everything it needs from its own position in the layout, which means the order of the cards on the canvas is the only thing that determines the order of the sequence. Reordering them in the layer list is enough to reorder the experience.

If you want a longer or shorter pause between finishing a card and the next one arriving, the spacer frame after each layer is the control. It is currently fifty percent of the viewport height. Shrinking it makes the next card follow almost immediately once this content bottoms out, and enlarging it adds a beat of plain page scrolling in between.

Project Two

This card uses exactly the same mechanism as the one beneath it. The override is applied per scroll container, so each card tracks its own internal scroll position independently of the others.

Only one card is ever active at a time. The active window opens the moment this card finishes pinning and closes the moment the next layer starts rising, so two cards can never fight over the same scroll input.

Event listeners are attached when the card becomes active and removed the moment it stops being active. Nothing is left bound to the window once you have scrolled past, so there are no leaks and no stale locks.

Touch input is tracked separately from wheel input. The vertical delta between touch points is applied to the same container, so the behaviour on a phone matches the behaviour on a trackpad.

At the boundaries the handler stops calling preventDefault and simply lets the event through. That is what makes the release feel like ordinary page scrolling rather than a scripted animation.

Viewport height is written as dynamic viewport height at runtime, so the layers do not jump when a mobile browser collapses its address bar mid scroll. The measured boundaries follow the same value.

If you resize the window everything is measured again on the next frame. The spacers are read from the live layout rather than assumed, so the active windows stay correct at any viewport size.

This is the final card in the test, so nothing rises to cover it. Once this content bottoms out the page simply continues to the end, and the lock never re engages on the way down.

This second card proves the override is not tied to a single instance. It is applied per scroll container, each one finds its own layer and its own spacers, and each tracks an entirely independent scroll position. Adding a third or fourth card requires no code changes at all, only the same three frames on the canvas.

The depth cue on the card underneath is driven by page scroll rather than by internal scroll, which is why it stays completely still while you read. The page is not moving during the lock, so the layer below holds its scale and opacity exactly where they were. It only begins to recede once the lock releases and the page starts travelling again.

Keeping the clip on the card and the scroll on a child inside it is what lets this text pass under the rounded corners cleanly. If the scroll container carried the radius instead, the corners would clip the scrollport rather than the content, and you would see square edges cutting across the text at the top and bottom of every scroll.

The margin around the card never changes during the pinned phase because the padding sits on the sticky layer rather than on the card. Whatever happens to the content inside, the gap to the viewport edge stays fixed, which is what sells the impression of a card floating above the layer behind it rather than a section that happens to be inset.

Dynamic viewport units are written over the authored heights at runtime. On a phone the address bar collapses as you scroll, which changes the viewport height mid gesture and would otherwise shift every measured boundary underneath you. Browsers that do not understand the unit simply ignore the declaration and keep the original value.

A deliberately fast flick can still carry the page past a card before its listeners have a chance to attach, because the lock cannot engage until the card has actually settled. The sticky positioning recovers on the very next event so nothing ends up in a broken state, but the card will have been skipped. That is a reasonable outcome for somebody clearly trying to get to the bottom in a hurry.

Keyboard scrolling deserves a mention because it bypasses the wheel entirely. The container carries a tab index so it can take focus, at which point the arrow keys, page keys and space bar drive it natively with no interception involved. Find in page also works, since the browser is scrolling a real scrollport rather than fighting a transform.

This is the last card in the test, so there is no layer above it and nothing to recede into. Once this content reaches its bottom the lock releases for the final time and the page simply runs on to the end. Replace all of this with real project content once the mechanism feels right to you.

Reading back up through this card works the same way in reverse. The routing function asks how much room exists above the current scroll position, absorbs exactly that much, and passes anything left over to the page. There is no separate code path for the upward direction, which is why it behaves consistently.

The one thing worth watching on a phone is that intercepting touchmove removes the platform momentum. Content follows the finger precisely while it is down and stops the moment it lifts, with no coasting. Whether that reads as controlled or as stiff is a judgement call best made on a real device rather than in a simulator.

Nothing here depends on the height of the content being known in advance. The container reports its own scroll height, so paragraphs can be added or removed freely and the lock adjusts on the next frame. That is the main practical advantage over driving a transform across a fixed distance.

The scrollbar has been left visible on purpose. It is the clearest possible signal that this region scrolls independently of the page, and hiding it tends to leave people scrolling a card they do not realise is scrollable. It can be hidden later with a stylesheet rule if the visual weight bothers you.

Because the page itself never moves during the lock, the layering transition underneath stays completely frozen while you read. The card below holds its scale and its opacity, and only resumes receding once the release hands scrolling back to the page. That separation is what keeps the two mechanisms from interfering.

That is the end of the placeholder copy. Scrolling further from here should release the lock and let the page run on to the bottom, with no further cards to cover this one. If any part of the sequence felt wrong on the way through, the numbers to reach for are the spacer heights and the two depth constants at the top of the override file.