Editorial Layouts

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

The install command below needs a licence to run; without one it returns 401.

How to install Pro components →See the plans →

Bring this into your project

Run this command in your project folder. The CLI adds the source and dependencies; then follow the usage example below.

npx webberui@latest add "https://webberui.com/r/cover-story-hero.en.json?t=<install token>"

New project or installation trouble? Start here →

Playground

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

26
Active edited usageDefault props
<CoverStoryHero/>

The complete example includes the preview layout and data. Install the component first, then paste this file into your project.

Installation

npx webberui@latest add "https://webberui.com/r/cover-story-hero.en.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

PropTypeDefaultDescription
mastheadstring—The masthead / main title, filled through an image mask and tucked behind the subject
subjectstring—URL of the subject portrait (a cut-out PNG is recommended); a built-in neutral silhouette is rendered when omitted
subjectAltstring—Alternative text for the portrait; when omitted, the portrait is treated as decorative
mastheadImagestring—URL of the image mask filling the masthead; a neutral gradient fills the letters when omitted
coverLinesCoverLine[][]Cover lines arranged in the four corner safe areas, flying off one by one on scroll
issuestring—Issue number, for example "No. 132"
datestring—Publication date, for example "JULY 2026"
pricestring—Cover price, shown beside the barcode
barcodebooleantrueWhether to show the barcode detail
heightstring"100svh"Height of the cover panel (any CSS length)
scrollDistancestring"70vh"Extra scroll distance needed for the cover lines to fly off
stickyTopnumber0Sticky offset of the cover from the top (px)
parallaxStrengthnumber26Maximum offset of the mouse parallax (px)
springConfigSpringOptions{ stiffness: 150, damping: 22, mass: 0.4 }Spring parameters for the parallax spring back
containerRefObject<HTMLElement | null>—Ref of the nested scroll container; defaults to the window as the scroll container

The CoverLine type:

FieldTypeDescription
corner"top-left" | "top-right" | "bottom-left" | "bottom-right"Which corner safe area the line sits in
kickerstringThe kicker (small heading) shown above the line
textstringThe 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 parallaxStrength and springs back.
  • Image-masked masthead: the masthead is filled with mastheadImage via background-clip: text, falling back to a neutral gradient when none is supplied. The font size scales with the panel width through the container query unit cqw, keeping the composition's proportions from desktop to mobile.
  • Scroll fly-off: the cover is pinned with sticky, and the useScroll progress staggers each line's departure across the first 60%, translating it along its corner's direction while rotating and fading it out to reveal the children body 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 an aria-label and the masthead is an <h1>; the decorative layers (portrait silhouette, barcode, vignette, issue bar) are all aria-hidden.
  • When subject is provided, subjectAlt can 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.