Sticky Scroll
Steps that scroll past a pinned picture, which changes in place to match the step being read.
Examples
Steps with a pinned picture
A day out with Fernpath
Four steps, one picture each
Plan the route at home
Draw the walk on the map, see the climbs ahead of time and the places to refill water on the way.Keep the map offline
The route and twenty kilometres around it stay on the phone, for the valleys where the signal drops.Walk without looking down
A short vibration before every turn, so the phone can stay in a pocket for most of the day.Share the day
Distance, time and the three photos you starred, in one card your friends can open without an account.
Stacked sections
Set up
Traders unload on the closed street. Each pitch is chalked on the ground with its number, and the covered stalls go up first.
Doors open
The welcome desk hands out coffee and the printed map. Most questions are about the bakery, which sells out before eleven.
Pack up
Stalls come down in reverse order. By three the street is swept and the tables are back in the hall for next Saturday.
Installation
npx shadcn@latest add https://ui.ndekocode.dev/r/motion-sticky-scroll.jsonComponent API
StickyScroll
The step that crosses the middle of the scrolling area is the active one. The picture of the active step fades in over the previous one, without sliding. The pinned panel repeats the pictures of the steps for sighted readers, so it is hidden from screen readers; below 36rem of width, each step shows its own picture above its text instead.
| Prop | Type | Default | Description |
|---|---|---|---|
| steps | StickyScrollStep[] | The steps, each with an id, a title, a description and its media. | |
| containerRef | RefObject<HTMLElement | null> | The scrolling element, when it is not the page. | |
| mediaSide | 'start' | 'end' | 'end' | The side of the pinned picture on wide layouts. |
| frameClassName | string | h-svh | Classes of the pinned panel. Its height should match the height of the scrolling area. |
| stepClassName | string | min-h-[70svh] | Classes of each step. Taller steps keep each picture on screen for longer. |
| className | string | undefined | Optional CSS class for the root element. |
StickySections
A wrapper for stacked sections. The sections stay pinned until the end of the wrapper, then leave together.
| Prop | Type | Default | Description |
|---|---|---|---|
| className | string | undefined | Optional CSS class for the wrapper. |
StickySection
A section pinned to the top of the scrolling area. Each section covers the one before it as it arrives; the scroll itself is the only movement.
| Prop | Type | Default | Description |
|---|---|---|---|
| className | string | h-svh | Classes of the section, merged over sticky top-0 flex flex-col. |