5

Stretchy Footer

Dia-style rubber overscroll — pull past the bottom and a rainbow aurora stretches up, then springs back when you let go.

Not a scroll-progress footer reveal — an overflow rubber-band. Scroll to the end of this page, then keep going: the page rolls up from the bottom and the rainbow aurora fills the stretch. Let go and it snaps back.

Stretchy Footer

Scroll past the end of this card — or play the rubber-band from here.

Tip: keep scrolling after you hit the bottom.

Installation

pnpm dlx shadcn@latest add @23rd/stretchy-footer

Or install straight from the public GitHub source registry:

pnpm dlx shadcn@latest add radiumcoders/23rd.dev/stretchy-footer

Usage

Use it as the scroll viewport. Put your page (and a normal footer block) in children. Wheel / touch past the bottom stretches the aurora; idle or release snaps it back. Honors prefers-reduced-motion (no stretch).

"use client"

import { StretchyFooter } from "@/components/ui/stretchy-footer"

export function Page() {
  return (
    <StretchyFooter className="h-svh bg-background">
      <main className="min-h-[120%] px-8 py-24 text-foreground">
        {/* …page content… */}
      </main>
      <footer className="px-8 pb-10 text-center text-muted-foreground">
        23rd — opinionated UI for shippers
      </footer>
    </StretchyFooter>
  )
}

On a full document (window scroll), pass windowScroll and mark the page root with data-stretchy-page so the content rolls up into the aurora:

"use client"

import { StretchyFooter } from "@/components/ui/stretchy-footer"

export function DocsChrome() {
  return (
    <>
      <div data-stretchy-page>{/* page content */}</div>
      <StretchyFooter windowScroll />
    </>
  )
}

Props

PropTypeDefault
childrenReactNode
scrollRefRefObject<HTMLElement | null>self as scroller
windowScrollbooleanfalse
contentSelectorstring[data-stretchy-page]
maxStretchnumber280
colorsstring[]spectrum red → pink
stiffnessnumber380
dampingnumber32
columnsnumber48
labelstringStretchy overflow
classNamestring