154

Letterbox Scroll Reveal

£7
or the whole Vault, £99

Pinned scroll section where a full-width picture opens from a hairline slit to full bleed like a film letterbox, with two lines of huge headline riding the slit's edges off the stage.

ScrollTrigger intermediate
6 more details
pinningscrubclip-pathmask-revealtext-animationscroll-storytelling

Released

About this effect

A pinned section that starts as almost nothing: a black stage, two lines of enormous type and one hairline of light between them. That hairline is your picture, cropped to its brightest line, with the colour spilling softly onto the black. Scrolling opens it vertically like a film letterbox.

Read the full effect overview

The opening comes in three moves on one scrub: a slow widening while the lines separate, a fast middle where the headline drives off the top and bottom of the stage, and a slow settle to exact full bleed. The picture lands sharp at 1:1 with no bars at any viewport shape, then a closing heading and sentence arrive over it. Any image or muted video works in the media slot, and the section can repeat as chapters down one page.

Letterbox Scroll Reveal - GSAP animation effect preview

What's included

9 items
  • Hairline start: the first frame is a single line of your picture across the full stage width, set by data-lsr-start
  • Focus line: choose which row of the picture sits in the slit, so a horizon or a product stays in view as it opens
  • Headline lines ride the slit's real edges, so the type can never overlap the picture at any scroll position
  • Type sizes itself to fill the stage, and stacks word by word on a phone so it still fills the width
  • Light from the picture spills onto the black while the slit is narrow, taken from the media itself with no extra asset
  • Lands at exactly full bleed and 1:1, measured at 1920x1080, 1200x675, 2560x1080 and 390x844
  • Headline, media and closing text are three plain slots; the media takes an img or a muted looping video
  • Several instances on one page run independently, each with its own distance, smoothing and start height
  • Reduced-motion, no-JS and blocked-CDN visitors get the picture full bleed with every line of text readable

Perfect for

5 use cases
  • Travel and expedition pages that open on one landscape and a big statement
  • Automotive and product launches where the hero shot deserves a cinematic reveal
  • Long-form editorial and brand stories, repeated as chapter openers with a new picture each time
  • Film, festival and photography sites that want a widescreen moment built from their own footage
  • Campaign pages that close the reveal on one short message over the full picture

How it works

2 sections

A pinned ScrollTrigger scrubs a single progress value, and everything on the stage is worked out from it: the slit's height, where the picture sits, how far the type has travelled and how much light spills out. Because the type's position always starts from the slit's real edge, the two can never collide.

The picture is laid out at its final size from the start and revealed by clipping, so it never scales past its resting size and lands sharp. The closing text is ordinary timeline work once the opening has finished. Touch devices get a shorter pin, and reduced-motion visitors a static full-bleed layout with no pin at all.

Plugins ScrollTrigger
Difficulty Intermediate
Includes HTML + JS + CSS source, documentation, AI setup prompt, lifetime updates

Lighthouse, as measured

Google Lighthouse on this effect's demo, from the latest scan. A measurement of the demo as shipped, not a promise for your page.

Accessibility
100
Best practices
100

No performance score, on purpose. That figure depends on how you deploy: your server's compression and caching, your CDN, the connection and the device doing the test, none of which the code controls. The same page can score very differently on two consecutive runs, so measure it where it will live.

The Vault opens this source and the whole library.

Each product gives you the HTML, CSS and JavaScript source, the full documentation and an AI setup prompt, licensed for unlimited personal and commercial projects. Every paid product is tested for desktop and mobile layouts, reduced-motion handling, animation cleanup and keyboard controls wherever there is something to operate.

One payment, over 300 products, and future additions to the library.

Documentation

Quick Start

1. Add to your HTML <head>:

In your downloadThe working code for this step, in index.html.

2. Add before the closing </body> tag:

In your downloadThe working code for this step, in index.html.

3. Add the section anywhere in your <body>:

In your downloadThe working code for this step, in index.html.

Using It With Your Own Design

What the effect needs from your markup: one .lsr root per section, with .lsr-window holding a .lsr-media, and .lsr-line--top and .lsr-line--bottom inside the headline. Everything is looked up inside its own root, so you can repeat the section down a page. .lsr-scrim, .lsr-payoff__heading, .lsr-payoff__body and the optional scroll cue (<p class="lsr-cue" aria-hidden="true">Scroll to open</p>) can each be left out. Heading levels are yours: use h1 for a page opener, h2 for a later chapter.

Any image or video goes in the media slot. Give the element the lsr-media class and it is handled the same way:

In your downloadThe working code for this step, in index.html.

Then tell the effect which row of the picture belongs in the slit with data-lsr-focus (see Options). A horizon, a skyline or the middle of a product all work well. The first frame is only a few pixels of that row, so pick one with some colour or light in it. Use media at least as wide as the stage for a sharp landing, because the browser upscales anything smaller.

Choosing the headline split: the type sizes itself so the wider line fills the stage, and both lines share one size, so two lines of similar length look best. .lsr-word is what lets each line stack on a phone. Wrap each word in one, or leave it out to keep a line together.

What is only the demo's styling: the Anton face, the #0a0a0a ground and the #f3efe6 ink. Change --lsr-face, --lsr-ground and --lsr-ink on .lsr. The payoff's size and position are ordinary CSS. If you lighten the picture or move the text, check the scrim in .lsr-scrim still gives your text 4.5:1.

CSS the effect depends on:

  • The block in style.css under prefers-reduced-motion: no-preference paints the closed first frame before the script runs. Keep it, along with the has-js line in your head, or the page flashes the open picture on load.
  • .lsr needs overflow: hidden, and its height of 100svh while live. The script measures that height, and all the opening is worked out from it.
  • .lsr-media keeps object-fit: cover with its object-position and transform-origin on --lsr-focus. This is what makes the landing exact at every viewport shape. To steer the crop sideways on a phone, change only the first value of object-position.

Options

Set these on the .lsr root.

Attribute Values Default Description
data-lsr-distance Percent of viewport height 260 How much scrolling the pin lasts. Touch devices use 72 percent of this.
data-lsr-scrub Seconds, or 0 for none 0.6 Smoothing between the scrollbar and the motion.
data-lsr-start Pixels 4 Height of the slit in the first frame.
data-lsr-focus 0 to 1 0.4 Which row of the picture sits in the slit, from the top.

Teardown

The script stores its GSAP context on window.gsapContext. Calling revert removes the pin, the generated light layer and all inline styles, and leaves the section in its static full-bleed layout:

In your downloadThe working code for this step, in script.js.

Accessibility

  • Reduced motion: the section is a static full-bleed picture with the headline and closing text visible, with no pin. A video in the media slot is paused. The change also applies live if the visitor changes the setting while the page is open.
  • No JavaScript or a blocked CDN: the same static layout, so nothing is ever hidden behind the script.
  • Headline: it stays one real heading whichever way the words stack, so screen readers read your full sentence once. The scroll cue and the light layer are aria-hidden.
  • Contrast: the demo's closing text clears 4.5:1 against the brightest pixel behind it at the sizes tested. Re-check it with your own picture.
  • Touch: the same mechanic on a shorter pin. On a portrait screen each line stacks word by word and refits to the width.
  • Images: give the media a useful alt, or alt="" if the headline already says what it shows.

Dependencies

Required:

  • GSAP 3.12+
  • ScrollTrigger plugin

The demo is pinned to GSAP 3.15.0. It uses Anton from Google Fonts, which you can replace with any face. No smooth-scroll library is needed.

Also in your download: the full source, worked examples, the events and programmatic API, and the class reference.

£7