Skip to content
animorio
IT
Back to the library

A layout set on the grid

Scroll, TextGSAPAdvancedCompressed weight: Demo 9.9 KBGSAP + ScrollTrigger 45 KBFreeDownload the zip

Scroll inside the preview

Twelve thin columns behind the page; in front of them four blocks, a title, a subtitle, a paragraph and a figure. As you scroll, each block is picked up as in a layout program, with its frame and handles, and jumps from column to column changing width and alignment, until the cover is laid out. Minimal style.

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>A layout set on the grid</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/archivo@5.3.0/wdth.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <!-- the cover of a made-up furniture catalogue, laid out while you scroll. Twelve thin columns stay still behind the
       page; four blocks, a title, a subtitle, a paragraph and a figure, are picked up one at a time like in a layout
       program and moved from column to column, changing width and alignment, until the final layout -->
  <main>
    <section class="apertura">
      <p class="piccolo">Tessel, catalogue cover</p>
      <h1 class="titolo">Four blocks,<br>twelve columns.</h1>
      <p class="piccolo piccolo--tenue">Scroll to lay out the page.</p>
    </section>

    <section class="racconto" data-racconto>
      <div class="palco">
        <header class="testa">
          <p class="piccolo">Catalogue cover</p>
          <p class="piccolo piccolo--tenue stato" aria-hidden="true">
            <span class="stato__riga" data-stato>Pasted in</span>
            <span class="stato__riga" data-stato>Centred</span>
            <span class="stato__riga" data-stato>On the grid</span>
            <span class="stato__riga" data-stato>Preview</span>
          </p>
        </header>

        <div class="pagina" data-pagina>
          <div class="griglia" data-griglia aria-hidden="true"></div>

          <h2 class="blocco" data-blocco="title"><span class="grande" data-grande>Tessel</span></h2>
          <p class="blocco blocco--sotto" data-blocco="subtitle">Furniture, made slowly.</p>
          <p class="blocco blocco--testo" data-blocco="text">Every piece starts as a drawing on squared paper and ends in a workshop of four people. We make tables, chairs and shelves in oak and ash, and we keep making only the ones that last.</p>
          <div class="blocco blocco--cifra" data-blocco="figure">
            <span class="grande grande--cifra" data-grande>48</span>
            <span class="blocco--dida" data-dida>pieces a year, all made by hand</span>
          </div>

          <div class="guida" data-guida aria-hidden="true"></div>
          <div class="guida" data-guida aria-hidden="true"></div>
          <div class="cornice" data-cornice aria-hidden="true">
            <span class="cornice__maniglia cornice__maniglia--a"></span>
            <span class="cornice__maniglia cornice__maniglia--b"></span>
            <span class="cornice__maniglia cornice__maniglia--c"></span>
            <span class="cornice__maniglia cornice__maniglia--d"></span>
            <span class="cornice__misura" data-misura>4 col</span>
          </div>
        </div>
      </div>
    </section>

    <section class="apertura apertura--fine">
      <h2 class="titolo titolo--medio">Set, and ready<br>for print.</h2>
    </section>
  </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="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.

29 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 “A layout set on the grid” from Animorio and fit it into my site

What it does

The catalogue cover of Tessel, a made-up furniture workshop, on a warm white with black ink and a single vermilion. The screen stops and behind the page twelve thin columns draw themselves from the top, one after another. The four blocks are pasted at the top left, one under the other, like freshly imported text. As you scroll, one block at a time is picked up: a vermilion frame with four handles closes around it, two guides run along its edges, the columns under it warm up and above the frame you read how many columns it takes. The block jumps from column to column, gets wider or narrower, the words slide into their new lines and the alignment changes: every word reaches its place on a measured spring, goes one pixel past and settles, and the lower lines arrive a moment after the first. Meanwhile the rest of the page steps back, lighter. The title always fills its block: it grows, gains weight and changes width on the wdth axis. First everything is centred, then it goes on the grid: a narrow, tall title at the top left, the figure at the top right, subtitle and justified text at the bottom. In the end the columns pull back like blinds and the figure lights up in vermilion. Everything follows the scroll, forwards and backwards.

How it works

Three layouts written as data

For every block and every layout the script has one line: the first column, how many columns it spans, where it stands (from the top, under the block before, from the foot of the page), the alignment as a number (0 left, 0.5 centre, 1 right) and whether it is justified. The title also has its width and weight on the variable axes, the figure its size. There are two sets of layouts, one for the computer and one for the phone, always on twelve columns.

Every word placed by hand

The text of the blocks stays in the page for screen readers, but what you see are its words, one per element, with their width measured once. The script breaks the lines itself at the width of the block and shifts them for the alignment and the justification: this way even the alignment can be blended, something text-align cannot do.

One number per block

The timeline, tied to the scroll with scrub SCRUB, moves a single number from 0 to 2 for every block: which layout it is in. Between two layouts column, width and position blend; with SNAP the column and the width are rounded to whole columns, and the block jumps from column to column as when you drag it with a snapping grid. A second number per block lights up the frame, the guides and the columns under it.

The springs

In GSAP’s ticker every word, the title and the figure chase their place on a damped spring (STIFFNESS is the strength, BOUNCE how far it overshoots): a column jump becomes a small snap that settles. The lower lines have a slightly softer spring (LAG), so they arrive after the first one, like a block pulled by a corner. The frame has its own spring too.

The title that fills its block

The title is set at 100 pixels and scaled up until it fills the width of the block. To know how wide it is at every mix of wdth and wght the script measures it once on a grid of values and then interpolates, instead of measuring it every frame. Its height is the height of the ink, read with measureText on a canvas, so the top of the title and the top of the figure sit on the same line.

Values to change

NameFileDefaultWhat it changes
SNAPscript.jstrueOn, the blocks jump from column to column as with a snapping grid; off, they glide without snapping.
STIFFNESSscript.js240The strength of the spring pulling every word to its place: higher is quicker.
BOUNCEscript.js0.35How far the words go past their place before settling: 0 not at all, 1 a real bounce.
LAGscript.js0.3How much later the lower lines arrive than the first: 0 all together, 0.6 far behind.
GUIDES_OFFscript.jstrueIn the end the columns pull back, like the preview of a layout program.
SCRUBscript.js0.6How many seconds the page takes to catch up with the scroll.

Try them in the Playground

When to use it

To tell the work of a graphic studio, a printer or a magazine, for the page that presents a catalogue or a new issue, or to explain a layout grid in a portfolio. It works with a few short blocks: a one-word title, a sentence, a paragraph, a figure.

On phones

The same, with adapted measures: still twelve columns, narrower and with a smaller gap; the phone layouts have wider blocks and the justified text runs the full width at the bottom.

With reduced motion

No jumps and no springs: every picked block fades out and comes back already in its new place; the columns appear and disappear with a fade.

Pitfalls

  • The title’s width read with getBoundingClientRect includes the scale that enlarges it: measured again on every ScrollTrigger refresh, when it is already big, it would come out as wide as it is enlarged and the block would get the wrong size. The transform is removed before measuring and put back afterwards.
  • Moved in the wrong order, the blocks passed over or landed on blocks still waiting (the subtitle going down crossed the paragraph). The order is chosen for every pass: towards the centre the lowest leaves first, towards the grid the title first, freeing the top; and while a block moves the others get lighter, so the picked one always reads on top.
  • Measuring the title every frame to fit it in its block means recalculating the layout sixty times a second. It is measured once on a grid of wdth and wght values and then interpolated.
  • Using the height of the line instead of the height of the ink, the top of the title and the top of the figure would not sit on the same line: a line box has a space above the letters that grows with the size. The ink is read with measureText (actualBoundingBoxAscent) once the font has arrived.

Libraries

GSAP 3.15.0, ScrollTrigger (GSAP) 3.15.0, Archivo (font variabile) 5.3.0.

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

Testing

Tested on 15 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