Skip to content
animorio
IT
Back to the library

The reportage gallery

Scroll, ImagesGSAPMediumCompressed weight: Demo 18 KBGSAP + ScrollTrigger 45 KBLenis 5.3 KBFreeDownload the zip

Scroll inside the preview

In a magazine reportage the page stops and, as you scroll down, a row of seven photographs laid out like a page proof slides sideways: each picture moves less than its frame, the one in the middle grows and takes its full colour, a thin line under the row tells you how far along the coast you are.

The code

A folder that runs on its own: index.html, style.css, script.js and the libraries from a CDN. The React and Vue tabs hold the same demo as a ready component, which switches its animations off when it leaves the page.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>The reportage gallery</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/source-serif-4@5.3.0/opsz.css">
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/source-serif-4@5.3.0/opsz-italic.css">
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/inter-tight@5.3.0/index.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <!-- a long read in a made-up coastal magazine, Tidewater. In the middle the page stops: while you scroll down, a row
       of seven photographs laid out like a page proof slides sideways. Each picture moves a little less than its frame,
       the one nearest the middle grows and takes its full colour, a thin line underneath tells how far along the coast
       you are. The photographs are drawn by the script as layered SVG -->
  <header class="testata">
    <p class="testata__nome">Tidewater</p>
    <p class="testata__motto">A journal of coasts and the people who work them</p>
  </header>

  <main>
    <article class="articolo">
      <header class="apertura">
        <p class="apertura__occhiello" data-entra>Reportage</p>
        <h1 class="apertura__titolo" data-titolo>The salt road</h1>
        <p class="apertura__catenaccio" data-entra>Seven days along a coast where the sea is still farmed by hand, from the salt pans of Marrow Bay to the last house on Kell Head.</p>
        <p class="apertura__firma" data-entra>Words and photographs by <a href="#" class="firma">Ines Arlow</a><span class="apertura__tempo">Twelve minute read</span></p>
      </header>

      <div class="testo">
        <p class="testo__primo">The rakers at Marrow Bay start before five. By then the crust on the pans has hardened in the night air, and it breaks clean under the wooden blade with a sound like stepping on frost. Arthur Penhale has worked these flats for thirty-one years, and his father before him; he still checks the brine with the back of his hand, the way you would check a bath for a child.</p>
        <p>The road south from the bay is not really a road. It is a chain of footpaths, causeways and farm tracks that used to carry salt to the market towns inland, and most of it now carries nobody at all. I walked it over seven days in late September, with one camera, two lenses and a notebook that got wetter every afternoon.</p>
        <p>What follows is the coast as it came, one stop at a time.</p>
      </div>
    </article>

    <!-- the gallery: the section is tall, the stage inside it sticks for the whole length of the scroll -->
    <section class="galleria" data-galleria aria-label="The salt road, in seven pictures">
      <div class="palco">
        <div class="palco__testa">
          <span>Tidewater <i>Reportage</i></span>
          <span class="palco__titolo">The salt road, in seven pictures</span>
        </div>

        <div class="palco__finestra" data-finestra>
          <div class="binario" data-binario>
            <div class="apri" data-apri>
              <p class="apri__occhiello">Portfolio</p>
              <h2 class="apri__titolo">Seven days, <em>one coast</em></h2>
              <p class="apri__testo">From Marrow Bay to Kell Head, on foot. Keep scrolling and walk it with her.</p>
              <svg class="apri__freccia" viewBox="0 0 64 16" aria-hidden="true"><path d="M1 8h60M53 1.5 61.5 8 53 14.5"/></svg>
            </div>

            <figure class="foto" style="--r: 1.5; --h: .5; --y: .34" data-foto="saline">
              <div class="foto__cornice"><div class="foto__scorre"></div></div>
              <figcaption class="foto__dida"><span class="foto__luogo">Marrow Bay</span> Salt pans at first light. The rakers start before five, while the crust is still cold. <span class="foto__fonte">Ines Arlow for Tidewater</span></figcaption>
            </figure>

            <figure class="foto" style="--r: .8; --h: .78; --y: .02" data-foto="faro">
              <div class="foto__cornice"><div class="foto__scorre"></div></div>
              <figcaption class="foto__dida"><span class="foto__luogo">Gull Rock</span> The light on the point, in a fog that sits there until noon. <span class="foto__fonte">Ines Arlow for Tidewater</span></figcaption>
            </figure>

            <figure class="foto" style="--r: 1.7778; --h: .44; --y: .5" data-foto="porto">
              <div class="foto__cornice"><div class="foto__scorre"></div></div>
              <figcaption class="foto__dida"><span class="foto__luogo">Sennick harbour</span> The last boats in before the tide turns. <span class="foto__fonte">Ines Arlow for Tidewater</span></figcaption>
            </figure>

            <figure class="foto" style="--r: .6667; --h: .84; --y: .1" data-foto="cucina">
              <div class="foto__cornice"><div class="foto__scorre"></div></div>
              <figcaption class="foto__dida"><span class="foto__luogo">Lower Fennick</span> Lunch at the Prowse farm: bread, lemons and a jug that has never left the table. <span class="foto__fonte">Ines Arlow for Tidewater</span></figcaption>
            </figure>

            <figure class="foto" style="--r: 1.25; --h: .58; --y: .3" data-foto="scogliera">
              <div class="foto__cornice"><div class="foto__scorre"></div></div>
              <figcaption class="foto__dida"><span class="foto__luogo">The Teeth</span> From the cliff path, a crabber heading for open water. <span class="foto__fonte">Ines Arlow for Tidewater</span></figcaption>
            </figure>

            <figure class="foto" style="--r: .75; --h: .74; --y: .06" data-foto="vicolo">
              <div class="foto__cornice"><div class="foto__scorre"></div></div>
              <figcaption class="foto__dida"><span class="foto__luogo">Port Elvan</span> Lanes too narrow for anything but feet and washing lines. <span class="foto__fonte">Ines Arlow for Tidewater</span></figcaption>
            </figure>

            <figure class="foto" style="--r: 1.5; --h: .52; --y: .4" data-foto="capo">
              <div class="foto__cornice"><div class="foto__scorre"></div></div>
              <figcaption class="foto__dida"><span class="foto__luogo">Kell Head</span> After sunset. One house, one lamp, and nothing west of it but the sea. <span class="foto__fonte">Ines Arlow for Tidewater</span></figcaption>
            </figure>
          </div>
        </div>

        <div class="corso" data-corso>
          <span class="corso__luogo">Marrow Bay</span>
          <div class="corso__linea" data-linea>
            <span class="corso__pieno" data-pieno></span>
          </div>
          <span class="corso__luogo">Kell Head</span>
        </div>
      </div>
    </section>

    <article class="articolo articolo--dopo">
      <div class="testo">
        <p>At Kell Head the path simply stops. There is a stile, a field of sheep that do not look up, and a single house whose owner, Maud Treloar, has kept a lamp in the west window every night since her husband went out with the pilchard boats in 1974 and came back late. She knows it is not needed any more. She lights it anyway.</p>
        <blockquote class="citazione" data-citazione>
          <p>The coast does not end. It just runs out of people to tell you where you are.</p>
        </blockquote>
        <p>Over the week I met eleven people still making a living from this water: three rakers, two crabbers, a lighthouse keeper with nothing left to keep, a baker and four members of one family who have turned a sardine cellar into a smokehouse. None of them would call it a dying trade. Most of them said, in one way or another, that it was simply a slow one.</p>
        <p>On the last morning the fog came in again over Gull Rock, and the salt road behind me disappeared into it one headland at a time. It seemed the right way to leave.<svg class="fine" viewBox="0 0 10 10" aria-hidden="true"><rect x="1" y="1" width="8" height="8"/></svg></p>
      </div>
      <footer class="nota">
        <p>Ines Arlow travelled at her own expense. Some names have been changed at the request of the people who carry them.</p>
      </footer>
    </article>
  </main>

  <script src="https://cdn.jsdelivr.net/npm/gsap@3.15.0/dist/gsap.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/gsap@3.15.0/dist/ScrollTrigger.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/lenis@1.3.26/dist/lenis.min.js"></script>
  <script src="script.js"></script>
</body>
</html>

Playground

Change values, colours and text with the controls and watch the animation respond live. Or write in the code yourself. Then download the folder with your changes.

58 values to change

Or ask Claude Code for it

With the Animorio connector, Claude Code takes it from here, guide included, and fits it into your project. Paste this request:

Take “The reportage gallery” from Animorio and fit it into my site

What it does

A long read in Tidewater, a made-up magazine about coasts and the people who work them: masthead, kicker, a big headline rising line by line out of its own baseline, standfirst, byline and the first paragraphs with a drop cap. Halfway through the article comes a band of darker paper and the page stops: as you scroll down, the row of photographs slides from right to left. It opens with a small title card («Seven days, one coast») followed by seven photographs from the trip, landscape and portrait, of different heights and at staggered levels as on a magazine page proof: salt pans at dawn, a lighthouse in fog, the harbour at dusk, a kitchen still life, the cliffs seen from above, a white lane with washing lines, a headland after sunset with a single lit window. Under each one sits its caption with the place, a line and the credit. Inside every frame the picture slides the other way, so it moves less than its frame and seems further away. The picture nearest the middle of the screen grows a little and has all its colours, the others stay slightly washed out; the caption lights up with it. Under the row runs a thin line, with Marrow Bay on the left and Kell Head on the right: it fills as you go, and one tick per photograph grows taller as that picture passes the middle. At the end of the row the page moves on and the article continues, with a pull quote whose rule draws itself and the small red end mark.

How it works

A tall section and a still stage

The gallery section is (1 + LENGTH) screens tall, measured in lvh, and inside it a position: sticky stage 100lvh tall: while the section scrolls the stage stays put, with no ScrollTrigger pin and no jumps on Safari, where lvh does not change when the address bar comes and goes. The stage is a three-row grid: the magazine's running head, the window with the row and the line of places.

A page proof made of three numbers

Every photograph carries in its inline style its ratio (--r), its height (--h) and its level (--y), as fractions of a single measure, --t, the height of the window minus the room for the captions. Width, height and top margin are calc()s of these three numbers: the row lays itself out on every screen, and on a phone it is enough to change --t.

One tween as the guide

A tween takes a value p from 0 to 1 with ease none and a ScrollTrigger with scrub (SCRUB seconds of lag, smooth even with Lenis). Everything is worked out from p every frame: the row moves by the travel times p, where the travel is the distance between the first position and the one with the last picture in the middle. The positions of the pictures are measured once (offsetLeft and offsetWidth, which transforms do not touch) on every refresh: nothing is read from the layout while scrolling.

Parallax, scale and colour from the distance

For each picture d is the distance of its centre from the middle of the screen. Inside the frame sits a holder wider by a fraction M on each side, moved by minus d over half the screen, times M, times the width: the picture travels slower than its frame and never shows its edges. From d also comes f, 1 in the middle and 0 far away, along a smoothstep curve: the frame grows by FOCUS_SCALE times f, the picture gets saturate(1 − DESATURATE × (1 − f)) and the caption moves down by as much as the picture has grown, so it never ends up underneath.

Drawn photographs and the line of places

The seven photographs are layered SVG built by the script: skies with several stops, haze and glows with feGaussianBlur, flipped reflections, a vignette and film grain (feTurbulence in overlay). Each one becomes a Blob and an image just once, so the blurs and the grain are computed once and scrolling stays light. The line under the row is a hairline with a second hairline on top in scaleX(p); the ticks sit where each picture passes the middle and grow with its f.

Values to change

NameFileDefaultWhat it changes
PARALLAXscript.js1How far the picture slides the other way inside its frame: 0 keeps it still in the frame, 2 makes it feel far away (the picture gets wider so its edges never show).
FOCUS_SCALEscript.js1.08How much bigger the picture nearest the middle gets (1 = all the same).
DESATURATEscript.js0.5How washed out the pictures away from the middle are: 0 all in colour, 1 black and white.
LENGTHscript.js4How many screens of scroll the gallery lasts: with more screens the row slides more slowly.
SCRUBscript.js0.9The seconds the row takes to catch up with the scroll: 0 glues it to the scroll, 2 lets it glide behind calmly.

Try them in the Playground

When to use it

For reportage and long reads with photographs, a photographer's portfolio, a travel diary, the pages of an online magazine, a travel agency or a festival: whenever a series of pictures should be looked at in a row, one at a time, without leaving the reading.

On phones

The same gallery with the sizes adapted: the pictures are measured on a height that never goes beyond the width of the screen, so even the widest one fits whole in the middle; the title card is narrower and the running head drops the title on the right. Scrolling with a finger moves it just like the mouse.

With reduced motion

Nothing slides on its own: the page does not stop, the row becomes a strip you swipe sideways with a finger or the trackpad, every picture is in full colour and at its own size, without parallax, and the line of places follows the strip. The text only fades in.

Pitfalls

  • The blurs and the grain of the photographs, left as inline SVG, were recomputed on every frame while the row slid and grew: turned once into an image (Blob and URL) they are drawn a single time and scrolling stays smooth.
  • With the middle picture bigger, its caption was covered by the edge of the picture: it moves down by half of what the picture has grown in height.
  • Positions read with getBoundingClientRect change with the scale and the travel of the row: offsetLeft and offsetWidth are used instead, which transforms do not touch, and they are only read again on a ScrollTrigger refresh.
  • A parallax stronger than the picture's margin showed the back of the frame: the picture's holder gets wider with PARALLAX, and the shift stops once the picture has left the screen.
  • On a phone the widest picture (16:9), measured on the screen's height alone, was wider than the screen itself: the reference measure is the smaller of the available height and a little more than the width.

Libraries

GSAP 3.15.0, Lenis 1.3.26, Source Serif 4 (font variabile) 5.3.0, Inter Tight (font variabile) 5.3.0.

Compressed with gzip, the three demo files weigh 18 KB; the libraries: GSAP + ScrollTrigger 45 KB, Lenis 5.3 KB.

Testing

Tested on 12 October 2026

  • Desktop: Done
  • Phone: Done
  • Reduced motion: Done
  • Safari on iPhone: To do

License

Use it in your own projects and in your clients’ projects. Do not resell it or redistribute it as is. GSAP stays under its own Standard license. Full license.

All animations