Scroll / Image / COMPONENT

Scroll Story Cards

A scroll-scrubbed image story where cards travel along a shallow arc and continuously shape the scene around the centered frame.

Live preview

Portraits / visual story

Scroll to explore

One scroll. Five changing frames.

The frame at the center shapes the image, color, and story.

  • Portrait of a woman in warm natural lightA little more warmthSoft light settles across the frame while an open horizon leaves room for the story to unfold. The colors shift gently as this portrait approaches the center.Explore
  • Portrait of a woman against a calm, muted backdropA moment of stillnessA quieter frame gives the details room to breathe. Small changes in light bring a different perspective into focus as the card rises.Discover
  • Portrait of a woman surrounded by soft green tonesSomewhere in the greenColor leads the way through a collection of small discoveries. The surrounding scene follows the portrait, blending into a soft green as it reaches the center.View story
  • Editorial portrait of a woman in late afternoon lightThe afterglowLate afternoon light softens the edges of the portrait. Its cooler palette carries the sequence into the next chapter without interrupting the scroll.Explore
  • Portrait of a woman with a warm, softly lit backgroundInto the violet hourThe final frame settles into a softer mix of violet and rose. Keep scrolling to see the last image leave the pinned scene and the page continue below.Read story

How it works

Document scroll progress continuously moves cards upward along a shallow arc. The card nearest the center influences the displayed story and interpolated scene color; scrolling backward reverses the same timeline.

Accessibility

Cards include configurable image alt text and semantic CTA links. Reduced-motion preferences soften the curved movement and depth transforms while preserving the scroll sequence.

Limitations

The pinned scene occupies the configured scroll distance. Use a shorter distance for compact pages, and provide image alt text and at least two cards for a meaningful transition.

Features

  • Keeps five separated image previews partially visible at the bottom of the pinned scene.
  • Moves the full card sequence upward continuously as the user scrolls; the incoming card follows a shallow arc into the center and then continues upward.
  • The card nearest the center supplies the active story without a click, horizontal exit, or snap.
  • Interpolates the hero background color from the card nearest the center.
  • Pairs a nearly square, gently tinted portrait with a location label, larger story copy, and a premium icon CTA anchored at the lower-right.
  • Pins the 400vh story sequence, then releases naturally into the following page content.
  • Supports custom card data, image alt text, CTA links, sizing, curve depth, overlay strength, and scroll distance.
  • Reduces the arc, rotation, and scale changes when reduced motion is requested while retaining vertical scroll progression.

Installation

Choose the CLI command or install the component manually.

Package manager
$ npx @istmx/ui add scroll-story-cards

Copies the install command for your selected package manager.

Dependencies

ReactMotionTailwind CSSclsxtailwind-merge@tabler/icons-react

Usage

Import the component from the file you copied it to, then use it like any other React component.

Usage
import ScrollStoryCards, { type ScrollStoryCard } from '@/components/ui/scroll-story-cards'
 
const cards: ScrollStoryCard[] = [
{
id: 'coast',
eyebrow: 'South coast',
title: 'The coast',
description: 'A slower frame at the edge of the water.',
image: '/images/coast.jpg',
imageAlt: 'A quiet coastline in late afternoon light',
color: '#e8e0f4',
overlayColor: '#cbbce5',
overlayOpacity: 0.34,
buttonLabel: 'Explore',
buttonHref: '/coast',
},
// Add more cards with their own images and colors.
]
 
<ScrollStoryCards
cards={cards}
eyebrow="Selected stories"
heading="A collection worth exploring."
description="Move through the frames by scrolling."
curveAmount={64}
cardWidth={156}
cardHeight={156}
overlayOpacity={0.38}
scrollDistance={400}
/>

Composition

Composition
ScrollStoryCards
├── Sticky story scene
│ ├── Fixed heading and eyebrow
│ ├── Rising image cards with copy and CTA
│ └── Five-card waiting stack
└── Natural scroll release

API reference

cardsScrollStoryCard[]

Cards with id, optional eyebrow, title, description, image, imageAlt, and a hex color for the scene background. overlayColor optionally tints the image and defaults to color; buttonColor defaults to overlayColor or color.

eyebrow? / heading? / description?string

Fixed scene label, heading, and optional supporting copy shown above the changing card content.

className?string

Classes applied to the outer scroll section.

curveAmount?number

Horizontal curve width in pixels as a card moves toward and away from the center. Defaults to 64.

cardWidth? / cardHeight?number

Maximum square size in pixels for the separated waiting previews. Defaults to 156px; featured cards cap at 620px wide and 17rem high on desktop.

overlayOpacity?number

Default color-overlay opacity from 0 to 1. Defaults to 0.38.

scrollDistance?number

Pinned story timeline in viewport units. Defaults to 400vh, then releases directly into following page content.

scrollContainerRef?RefObject<HTMLElement | null>

Optional scrollable ancestor for embedded previews. Omit it to track the document scroll position.

showCardLabels?boolean

Show each moving card title. Defaults to true.

onActiveChange?(card: ScrollStoryCard) => void

Called when a different card is nearest the center. Continuous visual motion remains scroll-linked.

The listed props match the current component implementation.

Data attributes

Scroll Story Cards does not expose custom data attributes.

Examples

Use at least two cards to see color and image blending. Scroll position continuously moves the nearest card through the center; stopping or reversing preserves the exact intermediate state. Cards require imageAlt text and may include CTA links.

Credits & inspiration

Created by Aryan (istmX) for ISTMX. The source-first, copy-and-own philosophy is inspired by shadcn/ui. About the creator