01
Pin, then translate
The section pins and its inner track slides on X. The page still scrolls vertically — nothing about the scrollbar or the wheel changes, which is why the navigation stays understandable.
Horizontal journey
← Creative LabExperiment — Horizontal journey
Horizontal sections are where accessibility usually gets quietly dropped. This one keeps the scrollbar honest, keeps focus reachable, and turns into a plain vertical list under reduced motion.
01
The section pins and its inner track slides on X. The page still scrolls vertically — nothing about the scrollbar or the wheel changes, which is why the navigation stays understandable.
02
Scroll length is the track width minus one viewport. Setting it by hand is how horizontal sections end up with dead space at one end or a panel that never fully arrives.
03
Tabbing to an offscreen panel scrolls the page so the browser can show it. Without this, keyboard users focus invisible controls — the single most common way this pattern breaks.
04
Each panel moves its own contents at a different rate than the track. The depth costs nothing and it is what stops the section reading as a slideshow.
05
Under reduced motion the whole thing becomes an ordinary vertical list. Same content, same order, no pinning, no horizontal movement at all.
The focus trap nobody notices
The track is moved with a transform, not a scroll. The browser therefore cannot scroll a focused child into view — it thinks everything is already on screen. Tab through the panels above with the keyboard: a focusin listener maps the focused panel back to a page scroll position.
invalidateOnRefresh
Scroll distance is a function, not a number, and ScrollTrigger is told to recompute it on refresh. Without that the section breaks on resize and on any font load that changes the track width — which is every first paint with a webfont.