WebberUI

Exploded View Scroll

A scroll-driven exploded view — once the section pins, the product's cut-out layers blow apart along the Z axis, the specs annotated on each layer reveal in order, and at the end of the scroll everything collapses back into the complete product and releases into the next section.

This is a WebberUI Pro component

Free during the launch campaign: sign up or sign in, then hit “Copy install command” in the preview above and it installs straight away — no payment, no credit card. The command below returns 401 while you are signed out.

How to install Pro components →See the plans →

Loading preview…
npx shadcn@latest add "https://webberui.com/r/exploded-view-scroll.json?t=<install token>"

Playground

Tune the props live — the code snippet updates as you go, so you can dial in the look you want before copying it.

88
120
900
3
<ExplodedViewScroll />

Installation

npx shadcn@latest add "https://webberui.com/r/exploded-view-scroll.json?t=<install token>"

Or, once registries are configured in components.json, install it as @webberui/exploded-view-scroll.

Usage

Pass layers ordered front to back (the first array entry is the topmost / farthest layer, the last is the bottommost / nearest). The stage inside the scroll track container gets pinned, the layers blow apart along the Z axis, and the spec copy attached to each layer reveals in order; at the bottom of the scroll the layers collapse back into the complete product and release into the next section as the track ends.

import { ExplodedViewScroll } from "@/components/ui/exploded-view-scroll";

<ExplodedViewScroll
  aria-label="Headphone exploded view"
  stageClassName="h-screen"
  layers={[
    {
      src: "/parts/glass.png",
      alt: "Glass panel",
      title: "Corning toughened glass",
      description: "0.4mm scratch-resistant coating",
      side: "right",
    },
    {
      src: "/parts/board.png",
      alt: "Mainboard",
      title: "N-series mainboard",
      description: "6 cores · 16GB",
      side: "left",
    },
    {
      src: "/parts/battery.png",
      alt: "Battery",
      title: "Silicon-carbon anode battery",
      description: "4820mAh · fast charging",
      side: "right",
    },
  ]}
>
  <h2 className="text-2xl font-semibold">Aero One</h2>
</ExplodedViewScroll>;

If the scrolling happens inside a nested overflow-y-auto container, pass that container's ref to container, set stageClassName to the container's visible height (for example h-[300px]), and set offsetTop to 0.

Props

PropTypeDefaultDescription
layersExplodedLayer[]The layers ordered front to back (see the table below)
scrollScalenumber3Height of the scroll track as a multiple of the pinned stage height — larger makes the explosion more leisurely
offsetTopnumber0Pinning position of the pinned stage (px)
spreadnumber88Vertical distance between two adjacent layers when exploded (px)
depthnumber120Z-axis depth between two adjacent layers when exploded (px)
perspectivenumber900Perspective distance (px); smaller makes the 3D perspective more dramatic
smoothbooleantrueWhether to smooth the scroll progress with a spring
containerRefObject<HTMLElement | null>Ref of the nested scroll container; defaults to the window as scroll container
aria-labelstring"Product exploded view"Accessible name for the stage
childrenReactNodeContent stacked in the center of the stage that does not intercept the pointer; fades out during the explosion
classNamestringApplied to the outermost scroll track container
stageClassNamestring"h-screen"The pinned stage container; override it with the container's visible height for nested scrolling
layerClassNamestringApplied to the positioning wrapper of each layer's visual (useful for controlling its size)

ExplodedLayer

FieldTypeDefaultDescription
srcstringSource of this layer's cut-out image; use either this or content
contentReactNodeCustom content for this layer; takes priority over src
altstring""Accessible description of the image / content
titlestringSpec title on the leader-line annotation
descriptionstringSpec description on the leader-line annotation
side"left" | "right"Alternates by indexWhether the annotation appears on the left or right side of the stage

How it works

  • The explosion follows a three-part timing of "spread → hold → collapse": on entry the layers separate along the Z axis, the middle section holds them apart so the spec copy can reveal in order, and at the bottom of the scroll they collapse back into the complete product before releasing naturally into the next section as the track ends.
  • The 3D is implemented with CSS perspective + translateZ (not WebGL): near layers grow under the perspective while far layers shrink, producing real depth.
  • The leader-line annotations align to the centers of the layers using their vertical positions after perspective projection, while the text stays horizontal and sharp rather than being scaled along with the layers.
  • The track height is computed automatically by measuring the pinned stage's real height and multiplying it by scrollScale, so it works whether the stage is a full-page h-screen or a nested h-[300px] container.
  • With smooth on, the scroll progress passes through a spring, giving the explosion a sense of momentum; with it off, it tracks scroll frame by frame.

Accessibility

  • When the user has "reduce motion" enabled at the system level, it is presented as a static captioned list instead: each layer's visual sits beside its spec title and description, with no scroll explosion at all.
  • The animated visuals and the leader-line annotations are all marked aria-hidden, and a separate sr-only spec list decoupled from the animation is provided so assistive technology can announce the full content.
  • The stage carries role="group" and an aria-label; the content overlaid at its center does not intercept pointer events (pointer-events-none).

On this page