Cover Story Hero
A magazine-cover hero composition — the masthead is image-masked and tucked behind the subject, cover lines are arranged in the four corners, the cursor drives parallax, and the cover lines fly off one by one on scroll to make way for the body copy.
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.
npx shadcn@latest add "https://webberui.com/r/cover-story-hero.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.
<CoverStoryHero />
Installation
npx shadcn@latest add "https://webberui.com/r/cover-story-hero.json?t=<install token>"Or, once registries are configured in components.json, install it as @webberui/cover-story-hero.
Usage
import { CoverStoryHero } from "@/components/ui/cover-story-hero";
<CoverStoryHero
masthead="ATLAS"
subject="/cover-portrait.png"
issue="No. 132"
date="JULY 2026"
price="$12"
coverLines={[
{ corner: "top-left", kicker: "Cover story", text: "What comes next for design systems" },
{ corner: "top-right", kicker: "Interview", text: "Animation-first interfaces" },
{ corner: "bottom-right", kicker: "Feature", text: "The revival of editorial layout" },
]}
>
<article className="prose mx-auto max-w-2xl px-6 py-16">…body copy…</article>
</CoverStoryHero>The cover panel defaults to a height of 100svh and uses the window as its scroll container. To embed it in a nested overflow-y-auto section, pass that section's ref to container and override height and scrollDistance as needed:
const scrollRef = React.useRef<HTMLDivElement>(null);
<div ref={scrollRef} className="h-[320px] overflow-y-auto">
<CoverStoryHero
masthead="ATLAS"
container={scrollRef}
height="280px"
scrollDistance="320px"
coverLines={coverLines}
>
{content}
</CoverStoryHero>
</div>Props
| Prop | Type | Default | Description |
|---|---|---|---|
masthead | string | — | The masthead / main title, filled through an image mask and tucked behind the subject |
subject | string | — | URL of the subject portrait (a cut-out PNG is recommended); a built-in neutral silhouette is rendered when omitted |
subjectAlt | string | — | Alternative text for the portrait; when omitted, the portrait is treated as decorative |
mastheadImage | string | — | URL of the image mask filling the masthead; a neutral gradient fills the letters when omitted |
coverLines | CoverLine[] | [] | Cover lines arranged in the four corner safe areas, flying off one by one on scroll |
issue | string | — | Issue number, for example "No. 132" |
date | string | — | Publication date, for example "JULY 2026" |
price | string | — | Cover price, shown beside the barcode |
barcode | boolean | true | Whether to show the barcode detail |
height | string | "100svh" | Height of the cover panel (any CSS length) |
scrollDistance | string | "70vh" | Extra scroll distance needed for the cover lines to fly off |
stickyTop | number | 0 | Sticky offset of the cover from the top (px) |
parallaxStrength | number | 26 | Maximum offset of the mouse parallax (px) |
springConfig | SpringOptions | { stiffness: 150, damping: 22, mass: 0.4 } | Spring parameters for the parallax spring back |
container | RefObject<HTMLElement | null> | — | Ref of the nested scroll container; defaults to the window as the scroll container |
The CoverLine type:
| Field | Type | Description |
|---|---|---|
corner | "top-left" | "top-right" | "bottom-left" | "bottom-right" | Which corner safe area the line sits in |
kicker | string | The kicker (small heading) shown above the line |
text | string | The main text of the cover line |
How it works
- Depth parallax: the masthead (the farthest layer) moves against the cursor and by the smallest amount, the subject portrait (the middle layer) moves with it, and the cover lines (the nearest layer) move the most, giving the three layers a sense of depth. The amount of movement is controlled by
parallaxStrengthand springs back. - Image-masked masthead: the masthead is filled with
mastheadImageviabackground-clip: text, falling back to a neutral gradient when none is supplied. The font size scales with the panel width through the container query unitcqw, keeping the composition's proportions from desktop to mobile. - Scroll fly-off: the cover is pinned with
sticky, and theuseScrollprogress staggers each line's departure across the first 60%, translating it along its corner's direction while rotating and fading it out to reveal thechildrenbody copy underneath. - Detail decoration: the issue/date detail bar and the pure-CSS barcode fade out first as you scroll, while the border and vignette reinforce the editorial-layout feel.
Accessibility
- When the user has "reduce motion" enabled at the system level, cursor parallax and scroll fly-off are disabled, and the cover keeps its full static composition (the sticky layout is preserved and the DOM structure is unchanged).
- The cover is a
<header>with anaria-labeland the masthead is an<h1>; the decorative layers (portrait silhouette, barcode, vignette, issue bar) are allaria-hidden. - When
subjectis provided,subjectAltcan supply alternative text for the portrait; omit it and the portrait is automatically treated as decorative. - Parallax only responds to
pointerType === "mouse", so touch devices never trigger the jitter.
Marginalia Article
Tufte-style sidenote reading layout — a main column paired with a fixed-width margin column, superscript numbers in the body connected to their sidenotes by hairlines, sidenotes fading in and highlighting in sync as you scroll, and an automatic fallback to inline expandable notes on narrow screens.
Interview Spread
A magazine interview layout — bold questions in a narrow left column alternating with serif answers in a wide right column, anchored by oversized quotation marks, with a speaker marker sliding along a sidebar rail and turns emerging in sequence as you scroll.