Skip to content
animorio
IT
Back to the library

The accordion-folded word

Text, 3DGSAP, CSS onlyAdvancedCompressed weight: Demo 7.7 KBGSAP 28 KBFreeDownload the zip

In the minimal style: a strip of paper with a big word printed on it folds like an accordion in 3D along vertical creases, closes almost shut, the narrow bundle turns over and the strip opens again on its other side, where the next word is printed. Every word fills the strip on the width axis of the typeface, and a thin dimension line measures the paper as it closes and opens.

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 accordion-folded word</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/anybody@5.3.0/wdth.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <main class="stage" data-stage>
    <!-- the words people read; everything drawn below is only their picture -->
    <h1 class="sr" data-read>Fold. Turn. Open. Again.</h1>

    <!-- one strip of paper with a word printed on each side. The script cuts it into panels along vertical creases,
         folds them like an accordion, turns the folded strip over and opens it on the other side, where the next
         word is printed. Above it, a dimension line measures how long the strip is -->
    <div class="scene" data-scene aria-hidden="true">
      <div class="shadow" data-shadow></div>
      <div class="strip" data-strip></div>
      <div class="quota" data-quota>
        <i class="quota__line" data-quota-line></i>
        <i class="quota__tick" data-quota-tick></i>
        <i class="quota__tick" data-quota-tick></i>
        <span class="quota__label" data-quota-label>420 mm</span>
      </div>
    </div>

    <!-- an invisible copy of the printed word, to measure its width and its baseline -->
    <div class="probe" data-probe aria-hidden="true"></div>
  </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.

19 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 accordion-folded word” from Animorio and fit it into my site

What it does

On a warm white page a bundle of paper, already folded, arrives from above: it lands with a little bounce and opens from the middle outwards, panel after panel, until it becomes a long strip with «FOLD» printed from edge to edge. The paper never goes perfectly flat again: it remembers its creases, and the panels turned towards the light are a touch brighter than the others. On the creases, top and bottom, two vermilion marks say where it folds; above, a thin dimension line measures the strip: 420 mm. After a moment the paper takes a breath (the creases open a hair), then the two ends push towards the middle and the strip closes like an accordion, with the dimension line shrinking along, into a narrow, deep bundle. The bundle rises, turns over on its horizontal axis (halfway round only its zigzag edge shows) and lands, and the strip opens again from the middle showing the back of the paper, a warmer shade, with «TURN» printed on it. As it opens it goes just past its creases and comes back, and the dimension line passes 420 mm by one millimetre before it settles. Then «OPEN», «AGAIN», and «FOLD» again, forever.

How it works

A chain of panels

The strip is made of PANELS CSS panels, each one an eighth of the strip wide and turned on its left edge (transform-origin: 0 50%) with rotateY. The panels turn one way and the other in turn, and each one starts where the one before ends: x grows by w·cos a and z drops by w·sin a. On every frame the chain is worked out again and centred, so the closing strip stays in the middle of the page. One number per panel, k, says how closed it is: 0 open on the crease the paper remembers (REST), 1 closed (CLOSE).

A whole word in every panel

Every panel has two faces with backface-visibility: hidden, and each holds the whole word, moved left by as many panel widths as its number: the panel cuts out its own piece with overflow: hidden. So the pieces always match and the word reads even when the strip is half closed. The back is turned with rotateX(180deg): when the whole strip turns over on its horizontal axis, it reads upright and in the same order, with no mirroring.

The word that fills the strip

The capitals of every word are FILL times the height of the strip (the cap height is measured with measureText on a canvas), and the margin is the same on all four sides. For the width, a binary search on the wdth axis of Anybody, from 50 to 150, finds the value that makes the word as long as the strip minus the margins: «FOLD» widens, «AGAIN» narrows. The baseline is measured with a zero-height inline-block aligned to it, so the text sits exactly in the middle.

Fold, turn over, open

The whole direction is one GSAP timeline that repeats, one step per word. The fold is a tween of k staggered from the edges to the middle with a hand-written ease: first the creases open by 4% (the paper takes a breath), then a damped spring closes it and goes a whisker past. Before the fold ends the bundle rises and turns by 180 degrees on rotateX, with another spring, and lands; the opening starts from the middle with a spring that goes past the resting crease and back. BOUNCE sets how far all the springs go past.

Which word on which side, the light and the dimension line

The front shows the word of the nearest even turn (2·round(turn/360)), the back the word of the odd turn it is in: each one changes only while its side faces away, so it is never seen changing. The light comes from the left and the front: the product of each face's normal and the light sets the opacity of a dark veil over the face. The dimension line projects the edges of the strip with the same perspective as CSS (P / (P − z)) and writes the millimetres; the shadow narrows with the strip and fades when the bundle rises.

Values to change

NameFileDefaultWhat it changes
WORDSscript.js['Fold', 'Turn', 'Open', 'Again']The words, one per side of the paper: every turn brings the next one. Short ones work best.
PANELSscript.js8How many panels the strip folds into.
CLOSEscript.js80How far the strip closes, in degrees: 90 would be shut flat.
RESTscript.js6The creases the paper remembers when it is open, in degrees: 0 is perfectly flat.
WEIGHTscript.js800The weight of the printed word, from 100 (a hairline) to 900 (black).
HOLDscript.js1.4How many seconds every word stays open before the strip folds again.
BOUNCEscript.js0.4How far the paper goes past its place before it settles: 0 not at all, 1 a lot.
SPEEDscript.js1The speed of the whole animation: 2 is twice as fast, 0.5 half as fast.

Try them in the Playground

When to use it

For the opening headline of a print shop, a graphic or printing studio, a stationer or a paper magazine, where the changing word is an object too; also for a landing page saying in three or four words what a product does, or for the wait before an event. It works with short words, which fill the strip without squeezing too much.

On phones

The same animation: the strip takes nine tenths of the width of the screen, the word and the panels are measured on it, and the fold, the turn and the springs stay the same, in proportion.

With reduced motion

Nothing folds and nothing turns: the strip fades in already open, with its light creases, and at every step the printed word fades out and back in as the next word.

Pitfalls

  • An accordion that closes and opens on the same side always shows the same faces: to see the back, the bundle has to turn over. On the vertical axis, halfway round the panels tilted by 80 degrees would come almost face on and a heap of word pieces would show; on the horizontal axis they always stay edge on, and halfway round only the zigzag edge shows.
  • The back has to be turned on the same axis as the turn, with rotateX(180deg): turned with rotateY(180deg), after the horizontal turn it would read upside down. This way piece n of the word on the back simply sits in panel n, in the same order as the front.
  • Changing the word of a face with a timeline callback does not hold when the timeline rewinds or jumps ahead: the word of every face is worked out from the angle of the turn on every frame, and changes only while the face looks away, so it is never seen changing.
  • Inside a GSAP timeline fromTo sets its starting values at once (immediateRender): the strip, which has to arrive closed, would show open for a frame. Every fromTo of the direction has immediateRender: false.
  • With panels exactly an eighth wide, at some angles a thread of the page can show between them: every panel is six tenths of a pixel wider and covers the crease.

Libraries

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

Compressed with gzip, the three demo files weigh 7.7 KB; the libraries: GSAP 28 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