Skip to content
animorio
IT
Back to the library

The service columns

Hover, TextGSAP, CSS onlyMediumCompressed weight: Demo 7.0 KBGSAP 28 KBFreeDownload the zip

In the minimal style: five narrow columns, one per service, each name standing upright. The column under the pointer widens on a spring while the others shrink, its name falls flat onto the one vermilion line, bounces a touch and settles, and its line of description writes itself underneath.

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 service columns</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>
  <main class="stage" data-stage>
    <header class="top">
      <span class="top__mask"><span class="top__item" data-top>Ostro</span></span>
      <span class="top__mask"><span class="top__item top__item--grey" data-top><span class="hint-mouse">Point at a column</span><span class="hint-touch">Tap a column</span></span></span>
    </header>

    <!-- five columns, one service each: the name stands upright in its narrow column; the one under the pointer
         widens on a spring, its name falls flat onto the vermilion line and its line of description writes itself -->
    <section class="cols" aria-label="Services" data-cols>
      <i class="floor" data-floor></i>

      <article class="col" tabindex="0" data-col>
        <i class="col__rule" data-rule></i>
        <h2 class="col__name" data-name>Strategy</h2>
        <p class="col__desc" data-desc>Positioning, naming and the story that comes before the logo.</p>
      </article>
      <article class="col" tabindex="0" data-col>
        <i class="col__rule" data-rule></i>
        <h2 class="col__name" data-name>Identity</h2>
        <p class="col__desc" data-desc>Marks, colour and rules that hold up at every size.</p>
      </article>
      <article class="col" tabindex="0" data-col>
        <i class="col__rule" data-rule></i>
        <h2 class="col__name" data-name>Type</h2>
        <p class="col__desc" data-desc>Custom lettering and variable fonts, drawn in house.</p>
      </article>
      <article class="col" tabindex="0" data-col>
        <i class="col__rule" data-rule></i>
        <h2 class="col__name" data-name>Motion</h2>
        <p class="col__desc" data-desc>Logos that move, title sequences and interface timing.</p>
      </article>
      <article class="col" tabindex="0" data-col>
        <i class="col__rule" data-rule></i>
        <h2 class="col__name" data-name>Web</h2>
        <p class="col__desc" data-desc>Sites built by hand: fast, light and easy to keep.</p>
      </article>

      <i class="mark" data-mark></i>
    </section>
  </main>

  <script src="https://cdn.jsdelivr.net/npm/gsap@3.15.0/dist/gsap.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 “The service columns” from Animorio and fit it into my site

What it does

The services page of a made-up studio, Ostro, on warm white paper: five columns parted by thin hairlines and a floor, a one-pixel line across that every name stands on. Strategy, Identity, Type, Motion and Web stand upright, written bottom to top, narrow, light and grey, in the variable typeface Archivo. When the page opens the hairlines between the columns come down from the top one after the other, the floor stretches out from the left and the names rise onto it while widening, a pixel too far and back; then the second column opens by itself. Pointing at a column, it widens on a spring and the others shrink to make room. Its name gets wider and heavier and meanwhile falls flat, turning about its foot like a plank tipping over, faster and faster; reaching the floor it lands on the one coloured line, bounces back up a few degrees and comes down again, and the vermilion line feels the hit and shakes by a couple of pixels. Then the description writes itself under the line, letter by letter. Moving to another column, the vermilion line runs there like a caterpillar, front edge first and back edge after, and the old name is lifted back upright while its description goes in one breath. Leaving the page, the last column stays open. With Tab and the arrow keys the columns open one at a time.

How it works

The columns on a spring

The five columns are position: absolute and the script writes their width. Each one has a share of the width, 1 when closed and WIDE when open, which chases its target on a damped spring worked out by hand (steps of 1/120 of a second on GSAP’s ticker, stiffness and damping in SPRING): the width is the share divided by the sum, so the columns always fill the whole row, even while they bounce.

The name that falls

The name turns about its bottom left corner (transform-origin: 0 100%). Upright it is rotated by −90 degrees, scaled down to fit the narrow column and shifted right by its own thickness, so its edge stays on the margin; the shift is the thickness times the sine of the angle and vanishes when the name is flat. The fall is a tween with power2.in, which speeds up like a weight, and the bounce is a small timeline of four steps.

The typeface’s axes

Archivo has a width axis from 62 to 125 and a weight axis from 100 to 900, both in Fontsource’s «wdth» file. Upright the names are at UPRIGHT, flat at FLAT: a single number from 0 to 1 carries width, weight, scale and colour together (with color-mix between the grey and the black). The type size is measured so that the longest name, lying flat, fills the open column.

The vermilion line

It is a one-pixel div stretched with scaleX between two edges, each on its own spring: the one going ahead is stiff, the one behind is soft, so moving from one column to another the line stretches and then gathers itself like a caterpillar. When the name lands it gets a push downwards and shakes on a third spring, short and well damped.

The description that writes itself

Every description is split into a span per letter, with the words held together by white-space: nowrap so a line never breaks inside a word, and a hidden copy for screen readers. The letters appear with a function stagger that counts the spaces too, at TYPE_SPEED letters a second, as soon as the name touches the line.

Values to change

NameFileDefaultWhat it changes
WIDEscript.js3.6How many times wider than the others the open column gets (a bit more on a phone).
SPRINGscript.js[230, 25]The columns’ spring: how stiff it is and how much it is held back (less, and it wobbles more).
FALLscript.js0.46How many seconds the name takes to fall from upright to flat.
BOUNCEscript.js4How many degrees the name bounces when it touches the line (0, no bounce).
TYPE_SPEEDscript.js42How many letters a second the description writes.
UPRIGHTscript.js[72, 320]Width (62 to 125) and weight (100 to 900) of the names standing in the narrow columns.
FLATscript.js[112, 640]Width and weight of the name lying flat in the open column.
OPEN_FIRSTscript.js1The column that opens by itself after the opening: 0 is the first.
--accentstyle.css#ff3d17The colour of the line under the open name, the only colour on the page.

Try them in the Playground

When to use it

For the services page of a design studio, an agency or a freelancer, for the sections of a portfolio or the departments of a shop, or for the courses of a menu: three to six entries, each with a short name and one line of description.

On phones

The same animation: the five columns stay in a row, the open column gets wider than on a computer and the floor moves up towards the middle of the tall screen. Tap or drag a finger over a column to open it; the name falls, bounces and the description writes itself over three lines.

With reduced motion

No springs, falls or bounces: the page fades in, the column pointed at is wide straight away with its name already flat on the line, and the description fades in whole.

Pitfalls

  • Turning the name about its bottom corner, upright it ended up entirely left of the margin, outside the column: it has to be shifted right by its thickness times the sine of the angle, so its edge stays still on the margin for the whole fall.
  • The type size has to be measured once Archivo has arrived: with the fallback the longest name went past the open column. The opening waits for document.fonts.load (a second and a half at most).
  • With the name resting a fixed 4 pixels above the floor, the tail of the y in Identity cut through the vermilion line: the gap is in em (0.06em), so it grows with the type.
  • If the name closing came up slowly, for a moment it stayed flat in a column that was already narrow and got cut: it is lifted with power3.out, quick at first, while width and weight come back gently.
  • The previews’ pilot sends pointerleave at every step: that is why leaving closes nothing, and the last column stays open.

Libraries

GSAP 3.15.0, Archivo (font variabile, assi wdth e wght) 5.3.0.

Compressed with gzip, the three demo files weigh 7.0 KB; the libraries: GSAP 28 KB.

Testing

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