Component
Sticky Scroll Section
A two-column scroll-driven section. Left column holds stacked text blocks (eyebrow, headline, body). Right column is a sticky image panel that crossfades to each item's image as the corresponding text block scrolls into view. After the last item the section exits normally.
Preview
This component requires scroll interaction — open the live preview to see the sticky image switch as you scroll.
Open interactive preview →How it works
Each text block gets a ref and is observed via IntersectionObserver with a rootMargin: '-35% 0px -35% 0px' trigger zone — the image switches when a block enters the middle 30% of the viewport.
The right column uses position: sticky; top: 0; height: 100vh so it pins to the viewport while the left column scrolls past. Framer Motion's <AnimatePresence mode="wait"> crossfades between images on index change.
Inactive text blocks dim to opacity: 0.3 via CSS transition so focus stays on the active item. On mobile the layout collapses to a stacked list — image above text for each item, no sticky behaviour.
Sanity fields
Available as stickyScrollSection in the Page builder. Each item in the Scroll items array maps to one text panel and one image.
| Prop | Type | Default | Description |
|---|---|---|---|
| theme | string | "dark" | "dark" or "light" — controls background and text colours. |
| items[].eyebrow | string | — | Optional small uppercase label in Electric blue. |
| items[].headline | string | — | Section headline. Required. |
| items[].body | text | — | Supporting body copy. Appears below the headline. |
| items[].image | image | — | The image shown in the sticky panel when this item is active. 3:4 aspect ratio works best. |
Content tips
- 2–5 items is the sweet spot — enough to create rhythm without overstaying
- Images at 3:4 (portrait) fill the panel best; landscape crops are cropped centrally
- Keep headlines short (4–8 words) — they stack and dim, so they need to land fast
- Each item should feel like a chapter, not a bullet point — give the body copy substance
- Dark theme pairs best with moody, contrasty photography; light theme with airy, bright images
Usage
import { StickyScrollSection } from '@/components/sections/sticky-scroll-section'
<StickyScrollSection
block={{
_type: 'stickyScrollSection',
theme: 'dark',
scrollItems: [
{
eyebrow: 'Landscapes',
headline: 'Where the light decides everything',
body: 'Every shoot starts before sunrise…',
image: { _type: 'image', asset: { _id: '…', url: '…' } },
},
// 2–5 items total
],
}}
/>// Via Sanity BlockRenderer — no extra code needed.
// Add to a Page document in Studio:
// Sections → Add item → Sticky Scroll Section