Skip to content
animorio
IT
All components

The bellows accordion

Accordions, 3D, Transitions, PhysicsGSAP, CSS onlyAdvancedCompressed weight: Demo 13 KBGSAP 28 KBFreeDownload the zip

The frequently asked questions of an accordion shop, made like the keyboard side of a real accordion: ivory and ebony keys on the left, which run on from one question to the next as a single keyboard, the question on a mother-of-pearl plate and a chrome tab on the right. Opening one, a red cloth bellows unfolds under it, pleat after pleat, in real 3D: light and shade on the faces, chrome corners on the folds, its edge going in and out. The answer is stamped in gold on the pleats, one line on each face, and reads as soon as the pleats lie flat; closing it, the bellows folds back up.

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 bellows accordion</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/roboto-serif@5.3.0/full.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <main class="stage">
    <!-- the questions of a shop that sells and mends accordions. Every question is a piece of the instrument's treble
         side: piano keys on the left, a mother-of-pearl plate with the question, a chrome register tab on the right.
         Opening one, a red bellows unfolds under it, pleat after pleat, and the answer is stamped in gold on the
         pleats, one line on each, readable once they have opened out. The bellows is drawn by the script: every face
         is a real element stretched onto its projected shape with a matrix3d. The answer itself stays a plain
         paragraph in a region for screen readers -->
    <div class="faq" data-faq data-autoclic>
      <div class="faq__item" data-item>
        <h3 class="faq__head"><button class="faq__q" type="button" id="faq-q1" aria-expanded="false" aria-controls="faq-a1"><span class="faq__keys" aria-hidden="true" data-keys></span><span class="faq__plate" aria-hidden="true"><span class="faq__pearl"></span><span class="faq__sheen"></span></span><span class="faq__text">Can I try an accordion before buying?</span><span class="faq__tab" aria-hidden="true"><span class="faq__rocker"><svg viewBox="0 0 16 10" focusable="false"><path class="faq__cut-lo" d="M2.5 2.6 8 7.4 13.5 2.6"/><path class="faq__cut" d="M2.5 2 8 6.8 13.5 2"/></svg></span></span></button></h3>
        <div class="faq__bellows" aria-hidden="true" data-bellows></div>
        <div class="faq__a" id="faq-a1" role="region" aria-labelledby="faq-q1" hidden><p data-answer>Of course. Book a slot and we set aside a quiet room with three sizes ready for you, and someone who plays shows you how the bellows should feel. Stay as long as you like.</p></div>
      </div>
      <div class="faq__item" data-item>
        <h3 class="faq__head"><button class="faq__q" type="button" id="faq-q2" aria-expanded="false" aria-controls="faq-a2"><span class="faq__keys" aria-hidden="true" data-keys></span><span class="faq__plate" aria-hidden="true"><span class="faq__pearl"></span><span class="faq__sheen"></span></span><span class="faq__text">Which size suits a beginner?</span><span class="faq__tab" aria-hidden="true"><span class="faq__rocker"><svg viewBox="0 0 16 10" focusable="false"><path class="faq__cut-lo" d="M2.5 2.6 8 7.4 13.5 2.6"/><path class="faq__cut" d="M2.5 2 8 6.8 13.5 2"/></svg></span></span></button></h3>
        <div class="faq__bellows" aria-hidden="true" data-bellows></div>
        <div class="faq__a" id="faq-a2" role="region" aria-labelledby="faq-q2" hidden><p data-answer>Most adults start on a 72-bass with 34 treble keys: light enough to hold through a lesson, wide enough for almost any song. Children usually begin on a 48-bass.</p></div>
      </div>
      <div class="faq__item" data-item>
        <h3 class="faq__head"><button class="faq__q" type="button" id="faq-q3" aria-expanded="false" aria-controls="faq-a3"><span class="faq__keys" aria-hidden="true" data-keys></span><span class="faq__plate" aria-hidden="true"><span class="faq__pearl"></span><span class="faq__sheen"></span></span><span class="faq__text">Do you repair old instruments?</span><span class="faq__tab" aria-hidden="true"><span class="faq__rocker"><svg viewBox="0 0 16 10" focusable="false"><path class="faq__cut-lo" d="M2.5 2.6 8 7.4 13.5 2.6"/><path class="faq__cut" d="M2.5 2 8 6.8 13.5 2"/></svg></span></span></button></h3>
        <div class="faq__bellows" aria-hidden="true" data-bellows></div>
        <div class="faq__a" id="faq-a3" role="region" aria-labelledby="faq-q3" hidden><p data-answer>Our workshop retunes reeds, replaces pads and valves and patches tired bellows. Bring yours in for a free look and you get a written quote within a week.</p></div>
      </div>
      <div class="faq__item" data-item>
        <h3 class="faq__head"><button class="faq__q" type="button" id="faq-q4" aria-expanded="false" aria-controls="faq-a4"><span class="faq__keys" aria-hidden="true" data-keys></span><span class="faq__plate" aria-hidden="true"><span class="faq__pearl"></span><span class="faq__sheen"></span></span><span class="faq__text">Can I rent one before I commit?</span><span class="faq__tab" aria-hidden="true"><span class="faq__rocker"><svg viewBox="0 0 16 10" focusable="false"><path class="faq__cut-lo" d="M2.5 2.6 8 7.4 13.5 2.6"/><path class="faq__cut" d="M2.5 2 8 6.8 13.5 2"/></svg></span></span></button></h3>
        <div class="faq__bellows" aria-hidden="true" data-bellows></div>
        <div class="faq__a" id="faq-a4" role="region" aria-labelledby="faq-q4" hidden><p data-answer>Any student model is yours for 25 euros a month. If you buy it within six months, every month you have paid comes off the price.</p></div>
      </div>
      <div class="faq__item" data-item>
        <h3 class="faq__head"><button class="faq__q" type="button" id="faq-q5" aria-expanded="false" aria-controls="faq-a5"><span class="faq__keys" aria-hidden="true" data-keys></span><span class="faq__plate" aria-hidden="true"><span class="faq__pearl"></span><span class="faq__sheen"></span></span><span class="faq__text">How should I store it at home?</span><span class="faq__tab" aria-hidden="true"><span class="faq__rocker"><svg viewBox="0 0 16 10" focusable="false"><path class="faq__cut-lo" d="M2.5 2.6 8 7.4 13.5 2.6"/><path class="faq__cut" d="M2.5 2 8 6.8 13.5 2"/></svg></span></span></button></h3>
        <div class="faq__bellows" aria-hidden="true" data-bellows></div>
        <div class="faq__a" id="faq-a5" role="region" aria-labelledby="faq-q5" hidden><p data-answer>In its case at room temperature, away from radiators and sunny windows, with the bellows strap closed so the folds rest evenly.</p></div>
      </div>
      <!-- the end of the instrument under the last question -->
      <div class="faq__foot" aria-hidden="true" data-foot></div>
      <!-- the answers are cut into lines here, at the width of the bellows -->
      <div class="faq__measure" aria-hidden="true" data-measure></div>
    </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.

35 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 bellows accordion” from Animorio and fit it into my site

What it does

On a white page, alone in the middle, a list of five questions that looks like the keyboard side of an accordion, with round corners at the top and the bottom. Down the left runs a keyboard of ivory keys with the black ones between them, one keyboard from top to bottom; beside it, past a chrome trim, each question is written dark on a mother-of-pearl plate, white with pink, green and blue lights, and on the right it has a chrome tab with a chevron cut into it: Can I try an accordion before buying?, Which size suits a beginner?, Do you repair old instruments?, Can I rent one before I commit?, How should I store it at home?. On arrival the list rises slightly and an invisible finger runs a scale down every key; then the second question opens. Opening a question, three of its keys stay down like a chord, the tab turns over and a red cloth bellows unfolds under the question: first the pleat near the keys, then the others downwards. The pleats are real, in perspective: the faces that look up catch the light, those that look down stay in shade, the deep of each pleat is darker and the right and left edges go in and out in a zigzag, with a dark tape and a gold thread along the sides and a chrome corner on every outer fold. Every face carries one line of the answer in gold letters: squashed and almost dark while the pleat is shut, it stretches and lights up as the pleat opens, and the glint of the gold changes with the slope of the face. The bellows goes a little past, lies flatter and comes back with a small bounce, and the questions below move down to make room. Opening another, the open one folds back up from the bottom, its keys come back up and the tab turns back. Under the mouse the question’s keys run a scale, the mother-of-pearl changes colour following the pointer, the letters grow fuller without getting wider and the bellows opens a finger’s width, just enough to show the red cloth.

How it works

The bellows’ pleats in 3D

Every pleat is two faces of cloth as long as one line (FACE, 26 pixels) hinged on the folds: the outer folds sit in front, at depth zero, and the inner ones set back by FACE times the sine of the pleat’s angle. The more a pleat opens, the lower the angle and the flatter its faces: each face is FACE times the cosine tall, so the cloth never stretches. Every pleat has its own angle, from 90 degrees (shut) to REST (open): the pleats near the keys start first and the ones at the bottom later, by CASCADE.

A matrix3d for every face

Every fold is projected from an eye EYE pixels in front of the middle of the bellows: the inner folds, further away, come out narrower, and the edge zigzags. Every face is a real element as wide as the list, with its line of text, the tape, the corners and the shading, and it is stretched onto its projected quad with a matrix3d worked out by hand: the homography that takes a rectangle onto four points (Heckbert’s method). The faces never overlap, because each goes from one fold to the next; half a pixel more above and below covers the antialiasing seams.

Light from the slope

Each face’s normal comes from its slope (the height and the depth it covers), and the light comes from above and in front: how far the face turns towards it decides a dark veil or a warm one over the cloth, and a gradient towards the inner fold darkens the deep in proportion to its depth. The gold line is a gradient clipped to the text that slides vertically with the face’s light: the glint runs over the letters as the pleat opens. The line only shows once the face is upright enough to be read.

The lines of the answer

The real answer stays a paragraph in a region with aria-labelledby, hidden from view but read by screen readers. For the bellows the script sets it word by word in a hidden box as wide as the column and gathers the words that share a top: those are the lines. The bellows has one face per line plus one of plain cloth above and below, always an even number, so it starts and ends on an outer fold. If the width changes, even halfway through opening, the lines are cut again and the bellows is rebuilt.

One spring, the keys and rest

How open the bellows is, is a spring with stiffness and damping worked out from a duration and a bounce (OPEN and BOUNCE), in steps of 1/240 of a second with the frame step capped at 1/30; past open the pleats lie a little flatter still. The questions below only move with translate3d, and the loop runs on GSAP’s ticker only while something moves. The keys are made by the script on the real keyboard pattern (C D E F G A B, with the black keys after C, D, F, G and A) and pressed through a CSS variable animated by GSAP; the tab turns over with rotationX in perspective.

Keyboard, touch and preview

The questions are buttons inside an h3 with aria-expanded and aria-controls; arrows, Home and End go from one to another, and with keyboard focus the bellows opens a crack as it does under the mouse. A finger touching a question runs the scale and opens the bellows a crack, the tap opens it. The list has data-autoclic: the preview’s click, which comes from a script, plays a whole round (the third question opens, then the fifth, then back to the second) and the script clicks that arrive during the round are ignored.

Values to change

NameFileDefaultWhat it changes
FIRSTscript.js1The question open when the page opens, from 0; −1 for none.
ONLY_ONEscript.jstrueOpening a question closes the open one; with false many can be open.
OPENscript.js1.25The seconds the bellows takes to open or close.
BOUNCEscript.js0.14How far the bellows goes past open and comes back (0 not at all).
RESTscript.js18How folded the pleats stay with the bellows open, in degrees (0 flat).
CASCADEscript.js0.6How far the pleats open one after another from the keys down (0 all at once).
EYEscript.js1300The distance of the eye from the bellows, in pixels: less, a deeper 3D.
PEEKscript.js0.15How far the bellows opens under the mouse, from 0 to 1.
GLISSscript.js0.04The seconds between one key and the next in the scale under the mouse.

Try them in the Playground

When to use it

For the frequently asked questions of an instrument shop, a music school, a craft workshop or any shop with a beautiful object to talk about: wherever there are many answers, one is read at a time and the site can afford a real piece of furniture. The red bellows says from afar which answer is open, and the pressed keys say it again.

On phones

The list is at most 640 pixels wide and on a phone narrows to the screen with a 16 pixel margin (358 on a 390 phone). Closed rows are 80 pixels tall on a computer and 72 on a phone, like the library’s other accordions; the keyboard goes down to 46 pixels, the questions to 16.5 and onto two lines, the bellows’ faces to 25 pixels and the answers to 15, onto four or five lines and so more pleats. A finger touching a question runs the scale on the keys and opens the bellows a crack, as the mouse over it does; the tap opens it. Same pleats, same light, same spring.

With reduced motion

No moving pleats: the bellows appears already open in its place, fading in, and closes at once; the chord’s keys go down and the tab turns without moving. No scale on the keys, no bellows opening a crack under the mouse and no glint running over the pearl. When the page opens the list fades in with the second question already open.

Pitfalls

  • With the eye at 760 pixels the faces at rest came out as trapezoids different enough to bend the lines: every other one looked italic, leaning one way and then the other. It is correct perspective, but it read as a mistake: the eye went to 1300 pixels, and the edge still zigzags when the pleats are deep.
  • The projected faces touch exactly on the folds, and antialiasing left a thread of the white page between them. Every quad is stretched half a pixel above and below, and the next face covers the seam.
  • With every pleat at the same angle the bellows opened like a roller shutter and the lines only all read together at the end. Every pleat now has its own delay, from the keys down: the lines light up one after another, in reading order.
  • A line printed on a face standing almost on its edge became a strip of squashed marks that looked like broken text. The line only shows once the face is upright enough (its cosine between 0.42 and 0.86), and the bellows opened a crack under the mouse shows nothing but cloth.
  • The lines depend on the font: cut before Roboto Serif had arrived, they came out too long or too short. The script waits for the font (for 1.2 seconds at most) and cuts everything again when it comes.
  • The focus ring on the plate sat under the mother-of-pearl and its sheen, which cover it entirely, and could not be seen. It moved onto the gloss that lies above them.
  • The preview’s click comes from a script onto the list: if each click opened a single question, the video would stop halfway. A click from a script starts a whole round in a GSAP timeline, and the clicks that arrive during the round do not restart it.

Libraries

GSAP 3.15.0, Roboto Serif (font variabile, con gli assi del peso, della larghezza, del corpo ottico e del grado) 5.3.0.

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

Testing

Tested on 17 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 components