Overlap Collage Layout
A magazine collage composition of overlapping elements, each lifting on hover.
CSS grid lets image blocks, text cards, tags, and badges overlap each other's column and row spans, building a magazine-style collage layout. Units reveal in a staggered sequence on entry, and on hover a unit lifts on a spring, straightens, and raises its z-index — as if picked up off the desk for a closer look.
Loading preview…
npx shadcn@latest add https://webberui.com/r/overlap-collage-layout.jsonPlayground
Tune the props live — the code snippet updates as you go, so you can dial in the look you want before copying it.
0.1
12
<OverlapCollageLayout />
Installation
npx shadcn@latest add https://webberui.com/r/overlap-collage-layout.jsonOr, once registries are configured in components.json, install it as @webberui/overlap-collage-layout.
Usage
import {
OverlapCollageLayout,
OverlapCollageItem,
} from "@/components/ui/overlap-collage-layout";
<OverlapCollageLayout columns={12} rows={10} className="h-[420px]">
<OverlapCollageItem column="1 / 9" row="2 / 9" rotate={-2}>
<div className="h-full rounded-2xl bg-gradient-to-br from-sky-400 to-teal-600" />
</OverlapCollageItem>
<OverlapCollageItem column="6 / 13" row="6 / 11" rotate={2} zIndex={2}>
<div className="h-full rounded-xl border bg-white p-5">Text card content</div>
</OverlapCollageItem>
</OverlapCollageLayout>Props
OverlapCollageLayout
| Prop | Type | Default | Description |
|---|---|---|---|
columns | number | 12 | Number of columns in the layout grid; children position themselves with gridColumn spans |
rows | number | 10 | Number of rows in the layout grid; children position themselves with gridRow spans |
stagger | number | 0.1 | Reveal stagger interval (seconds); children appear in DOM order |
liftAmount | number | 12 | How far a unit lifts on hover (px) |
straightenOnHover | boolean | true | Whether to straighten the unit's rotation on hover |
className | string | — | Forwarded class; this is a good place to set the overall height or aspect ratio |
children | React.ReactNode | — | Collage content — put several OverlapCollageItems here |
OverlapCollageItem
| Prop | Type | Default | Description |
|---|---|---|---|
column | string | — | gridColumn positioning string (for example "1 / 9"); overlapping spans is what creates the overlap |
row | string | — | gridRow positioning string (for example "2 / 9") |
rotate | number | 0 | Rotation at rest (degrees), for the casual feel of a collage |
zIndex | number | 1 | Stacking level at rest; raised automatically on hover or focus |
className | string | — | Forwarded class, merged onto the unit's outer element |
children | React.ReactNode | — | Unit content: image blocks, text cards, tags, badges, and so on |
Accessibility
- When the user has "reduce motion" enabled at the system level, the reveal only fades in without movement or scaling, and hover no longer lifts or enlarges
- When a focusable element inside a unit (a link or button) takes keyboard focus, that unit raises its z-index automatically so it stays fully visible despite the overlap
- The collage only affects visual positioning; content keeps its original DOM order, so screen readers read it in sequence regardless of the overlap
- The reveal animation uses
viewport onceso it plays a single time and never repeatedly interrupts reading