Components

Parallax

Translates its content as it scrolls for a depth effect.

php artisan blatui:add parallax

Scroll the page — the photo drifts slower than the text card in front of it.

Mountain landscape

Depth on scroll

The image moves at a fraction of the scroll speed, so it appears to sit further away than the caption resting on top of it.

{{--
    Reacts to PAGE scroll. The tall frame below gives the effect room to read:
    scroll the page and the background image drifts at a different speed than the
    foreground card, creating depth.
--}}
<div class="space-y-6">
    <p class="text-muted-foreground text-sm">
        Scroll the page — the photo drifts slower than the text card in front of it.
    </p>

    <div class="relative h-[28rem] overflow-hidden rounded-xl border">
        {{-- Background layer: parallaxes (lags) behind the foreground. --}}
        <x-ui.parallax :speed="0.4" class="absolute inset-0">
            <img
                src="https://picsum.photos/seed/blatui-parallax/1200/900"
                alt="Mountain landscape"
                class="h-[34rem] w-full object-cover"
            />
        </x-ui.parallax>

        {{-- Foreground content sits in front, scrolling with the page (no parallax). --}}
        <div class="absolute inset-0 flex items-end bg-gradient-to-t from-black/70 via-black/20 to-transparent p-8">
            <div class="space-y-2 text-white">
                <h3 class="text-2xl font-semibold">Depth on scroll</h3>
                <p class="max-w-md text-sm text-white/80">
                    The image moves at a fraction of the scroll speed, so it appears to
                    sit further away than the caption resting on top of it.
                </p>
            </div>
        </div>
    </div>
</div>

Layered

Scroll the page — each layer moves at its own speed, the label stays put.

Layered parallax
{{--
    Reacts to PAGE scroll. Two parallax layers at different speeds plus a static
    foreground build a sense of depth — back drifts most, mid less, label is fixed.
--}}
<div class="space-y-6">
    <p class="text-muted-foreground text-sm">
        Scroll the page — each layer moves at its own speed, the label stays put.
    </p>

    <div class="relative h-[26rem] overflow-hidden rounded-xl border bg-muted">
        {{-- Far layer: largest drift (highest speed). --}}
        <x-ui.parallax :speed="0.6" class="absolute inset-0">
            <div class="flex h-[32rem] w-full items-center justify-center">
                <div class="size-72 rounded-full bg-primary/20 blur-2xl"></div>
            </div>
        </x-ui.parallax>

        {{-- Mid layer: smaller drift. --}}
        <x-ui.parallax :speed="0.25" class="absolute inset-0">
            <div class="flex h-[30rem] w-full items-center justify-center">
                <div class="grid grid-cols-3 gap-4">
                    @foreach (range(1, 6) as $i)
                        <div class="size-16 rounded-xl border bg-card shadow-sm"></div>
                    @endforeach
                </div>
            </div>
        </x-ui.parallax>

        {{-- Foreground label: no parallax, scrolls with the page. --}}
        <div class="absolute inset-x-0 bottom-0 p-8">
            <div class="inline-flex items-center gap-2 rounded-full border bg-card px-4 py-2 text-sm font-medium shadow-sm">
                <x-lucide-layers class="size-4 text-primary" aria-hidden="true" />
                Layered parallax
            </div>
        </div>
    </div>
</div>