A stacked-layer blur that ramps smoothly from sharp to fully blurred toward an edge, for fading content under a fixed header or above a scroll boundary. React.
Made by AxylScroll the panel — content fades under a progressive blur at the top and bottom edges.
The wrapping element needs position: relative (or any positioning context) — ProgressiveBlur
renders as an absolutely positioned overlay pinned to one edge via direction.
Keep scrolling content as a sibling
ProgressiveBlur blurs whatever sits behind it in the same stacking context. Mount it as a
sibling of the scrollable element (both inside the relative wrapper), not as a child of it —
otherwise it scrolls away with the content instead of staying pinned to the edge. Also avoid
overflow: hidden or a transform on an ancestor between the two: either creates a new
stacking/containing context and the blur will sample the wrong content, or get clipped
entirely.
A single backdrop-filter: blur() with a gradient mask blurs uniformly, then fades in opacity —
it doesn't get blurrier toward the edge, just fainter. ProgressiveBlur instead stacks several
layers, each with its own blur radius and a mask that isolates a band of the fade zone, so the
blur radius itself ramps up toward the edge. More layers reads smoother, at the cost of more
backdrop-filter paints:
Set fade={false} to skip the trailing solid-color layer and let the blurred content show
through all the way to the edge, instead of fading out to --pb-background:
ProgressiveBlur reads --pb-background for its solid-fade layer, defaulting to your app's own
--background shadcn token when present. Override it directly if the edge sits on a different
surface than the page background:
| Prop | Type | Default |
|---|---|---|
direction? | "top" | "bottom" | "left" | "right" | "bottom" |
size? | string | "6rem" |
maxBlur? | number | 12 |
layers? | number | 6 |
fade? | boolean | true |
className? | string | - |
Reach for ProgressiveBlur at the boundary of any scrollable region where content needs to fade
out gracefully instead of clipping abruptly — under a sticky header, above a fixed footer, or at
the edges of a horizontally scrolling rail. It reads as glass rather than a hard cutoff because
the blur intensity itself increases toward the edge, matching how out-of-focus content actually
looks.
ProgressiveBlur is aria-hidden and pointer-events-none — it's a purely visual overlay and
never intercepts clicks or scroll. backdrop-filter itself has no motion to disable, but stacking
6–16 of them is a real paint cost, so when the OS Reduced Motion setting is on, ProgressiveBlur
collapses to a single layer regardless of layers — same silhouette, far less work per frame.
Adapted from gxuri (Skiper UI). Independent implementation for the Sora UI registry. Not affiliated with the original authors.
Highlight
A shared Motion-powered highlight that slides between items on hover, or fades per-item on click. React component.
Magnetic Cards
A fanned stack of cards that fling away from the cursor on release, with GSAP InertiaPlugin easing each one back to rest. React component.
Built by Axyl. A motion-first component registry for React.
Last updated: 9/14/2026
Help keep SoraLabs moving.
Every contribution helps us build and maintain open-source tools for the community.
Sponsor on GitHubLorem ipsum dolor sit amet consectetur adipisicing elit. Obcaecati, reiciendis eum vitae nostrum, temporibus repudiandae voluptatibus, natus iure ipsa velit odit quibusdam illum.
Quaerat cumque laudantium libero reprehenderit perferendis quo nulla voluptate. Repellat tenetur labore exercitationem dicta libero voluptate suscipit, iusto ea assumenda.
Ipsa enim, quidem atque modi error eaque, debitis perferendis, hic iste libero dignissimos ea. Quod inventore beatae aspernatur nulla rem perferendis aperiam at debitis.
Quod reiciendis in similique reprehenderit commodi quo blanditiis nobis hic ea optio illum placeat officia alias quasi autem earum quos obcaecati, voluptatum corporis quisquam.
Quisquam iste, quas explicabo omnis harum aut quam adipisci, voluptatem saepe accusantium doloribus repellendus amet culpa magnam ex et dolores accusamus commodi facere.
Beatae deserunt sequi id eos libero suscipit totam cum, sed architecto atque quisquam et incidunt quod fuga ullam repellat assumenda quos ab, voluptatum sint nesciunt.