StickySectionStack
Stack child sections as sticky layers that scale down progressively as the container scrolls.
StickySectionStack is a client component that makes each child a sticky layer. Earlier layers shrink as later ones scroll over them, driven by scroll progress. Use it for process or feature sections on long pages. It depends on motion/react.
Plan
Define scope, owners and milestones.
Build
Ship small increments behind feature flags.
Ship
Roll out gradually and watch the metrics.
Import#
import { StickySectionStack } from "@reactberry/system/blocks";
Usage#
import { StickySectionStack } from "@reactberry/system/blocks";
import { Box, Text } from "@reactberry/system/elements";
const steps = ["Plan", "Build", "Ship"];
export default function Process() {
return (
<StickySectionStack
maxWidth="960px"
mx="auto"
sectionMinHeight="70vh"
sectionProps={{ skin: "card", shape: "rounded", p: "l" }}
>
{steps.map((step) => (
<Box key={step} minHeight="50vh">
<Text as="h2" fontSize="xxxl" fontWeight="700">
{step}
</Text>
</Box>
))}
</StickySectionStack>
);
}
Examples#
Tight stack#
Lower stickyStep, scaleStep and a higher minScale give a denser stack with less scaling.
API#
StickySectionStack#
| Prop | Type | Default | Description |
|---|---|---|---|
children* | ReactNode | — | Each non-empty child becomes one sticky section |
topPadding | string | 10vh | Top padding of the container |
stickyTop | string | 4vh | Sticky |
stackOffsetBase | number | 0 | Base vertical offset in pixels applied to each section |
stickyStep | number | 24 | Extra offset in pixels added per section index, so stacked sections peek out below each other |
scaleStep | number | 0.06 | Scale reduction per section that follows |
minScale | number | 0.82 | Lower bound for the final scale |
sectionMinHeight | string | auto |
|
bottomPadding | string | 30vh | Bottom padding of the container |
sectionProps | BoxProps | — | Props spread onto the inner |
children (ReactNode, required): each non-empty child becomes one section. All remaining BoxProps are spread onto the container Box. StickySectionStackProps is exported from the component module but not from @reactberry/system/blocks.
Accessibility#
- Sections are plain
divelements with no roles; content order is unchanged. - When the user prefers reduced motion, sections render in normal flow without sticky positioning, scaling, or container padding;
sectionPropsand the remaining props still apply.
Notes#
- Section
indexscales from 1 tomax(minScale, 1 - (total - index - 1) * scaleStep)over scroll progress fromindex / totalto 1. The last section never scales. - Scroll progress uses
useScrollwith the container astargetand offset["start start", "end end"]. No scrollcontaineris passed, so progress follows the window scroll even when the stack sits inside a scrollableBox; sticky positioning still follows the nearest scroll container. - Children are keyed by index after
Children.toArray, so reordering children remounts sections.