Edge blur
Stacked backdrop-blur layers with a gradient mask. Blurs sit outside the scroll layer so they stay pinned to the frame; only the inner panel scrolls. transform-gpu on the frame keeps fixed blurs inside this preview instead of the viewport.
Paragraph 1. Layers use pointer-events-none so the scroll container still receives wheel and touch events.
Paragraph 2. Layers use pointer-events-none so the scroll container still receives wheel and touch events.
Paragraph 3. Layers use pointer-events-none so the scroll container still receives wheel and touch events.
Paragraph 4. Layers use pointer-events-none so the scroll container still receives wheel and touch events.
Paragraph 5. Layers use pointer-events-none so the scroll container still receives wheel and touch events.
Paragraph 6. Layers use pointer-events-none so the scroll container still receives wheel and touch events.
Paragraph 7. Layers use pointer-events-none so the scroll container still receives wheel and touch events.
Paragraph 8. Layers use pointer-events-none so the scroll container still receives wheel and touch events.
Paragraph 9. Layers use pointer-events-none so the scroll container still receives wheel and touch events.
Paragraph 10. Layers use pointer-events-none so the scroll container still receives wheel and touch events.
Paragraph 11. Layers use pointer-events-none so the scroll container still receives wheel and touch events.
Paragraph 12. Layers use pointer-events-none so the scroll container still receives wheel and touch events.
Bottom blur row 1
Bottom blur row 2
Bottom blur row 3
Bottom blur row 4
Bottom blur row 5
Bottom blur row 6
Bottom blur row 7
Bottom blur row 8
Top blur row 1
Top blur row 2
Top blur row 3
Top blur row 4
Top blur row 5
Top blur row 6
Top blur row 7
Top blur row 8
Installation
pnpm dlx shadcn@latest add https://cult-ui.com/r/edge-blur.json
Usage
import { BottomBlur, EdgeBlur, TopBlur } from "@/components/ui/edge-blur"Full viewport (typical)
Place near the root of your page or layout. The component uses position: fixed and spans the width of the viewport.
export function PageChrome() {
return (
<>
<main>{/* … */}</main>
<BottomBlur height={80} />
</>
)
}Inside a card, modal, or preview
If an ancestor has a transform, filter, or perspective (other than none), fixed descendants are positioned relative to that ancestor instead of the viewport. Use that to contain the blur inside a rounded panel.
Put EdgeBlur outside the scrolling element. If scroll lives on the same parent as the blur, the blur becomes part of the scrollable overflow and will move with the content.
<div className="relative isolate h-96 transform-gpu overflow-hidden rounded-xl border">
<div className="absolute inset-0 overflow-y-auto">
<div className="min-h-[800px] p-4">{/* long content */}</div>
</div>
<EdgeBlur position="bottom" height={72} />
</div>API
| Export | Description |
|---|---|
EdgeBlur | position "top" | "bottom", height (px) |
TopBlur | Top edge; optional height |
BottomBlur | Bottom edge; optional height |
Notes
- Uses repeated
backdrop-filterlayers with increasing blur radius and a CSS mask for a smooth falloff. - Does not block pointer events (
pointer-events-none).