Skip to content

Sticky Surface

A sticky surface component with scroll-based effects (border, shadow, surface swap, shrink, glass).

Scroll inside!

---
import { Button } from '@bejamas/ui/components/button';
import { StickySurface } from '@bejamas/ui/components/sticky-surface';
---
<div class="overflow-y-auto max-h-[320px] w-full bg-border px-8 border-border">
<div class="h-[1000px] bg-muted">
<StickySurface effects={["line", "elevate"]} threshold="1rem" observeStuck class="bg-background p-4 flex justify-between items-center">
<p>Scroll inside!</p>
<div class="flex items-center gap-2">
<Button size="sm" variant="outline" class="group-[.is-stuck]/surface:opacity-0 will-change-transform group-[.is-stuck]/surface:blur-sm transition-all duration-300 ease-out">Log in</Button>
<Button size="sm" class="w-24 group-[.is-stuck]/surface:w-28 duration-500 ease-out">
<span class="group-[.is-stuck]/surface:blur-sm group-[.is-stuck]/surface:opacity-0 absolute group-[.is-stuck]/surface:hidden transition-discrete duration-500 ease-out">Contact</span>
<span class="group-[.is-stuck]/surface:blur-none group-[.is-stuck]/surface:opacity-100 group-[.is-stuck]/surface:delay-150 opacity-0 transition-all blur-sm duration-500 ease-out">Get a demo</span>
</Button>
</div>
</StickySurface>
</div>
</div>
Terminal window
bunx bejamas add sticky-surface
---
import { StickySurface } from '@bejamas/ui/components/sticky-surface';
---
<StickySurface effects={["line", "elevate"]} threshold="1rem">
<!-- Your content here -->
</StickySurface>
PropTypeDefault
asHTMLTag"div"
thresholdstring | number"16px"
effectsArray<"line" | "elevate" | "backdrop">[]
classstring""
stylestring""
observeStuckboolean