Accordion Fold
An accordion where each panel unfolds like a folded sheet: the height opens in 0.5 s to the content's real size while the text pivots from −90° to 0° around its top edge, in a 600 px perspective, with a slight bounce. One section open at a time, aria-expanded, closed panels out of the tab order, a 0.15 s fade when the user reduces motion.
Updated
This effect is part of Effect.Labs — 840 vanilla effects, some free, some premium. Transitions has 52 effects, including 9 free. Explore the category →
3 usage examples



How it works
Each section is an .accordion-fold-item: a real header <button> with an arrow, then an .accordion-fold-content panel holding the .accordion-fold-inner text. Closed, the panel is max-height: 0, overflow: hidden and visibility: hidden; it also carries perspective: 600px, the distance the fold is seen from. The text waits at rotateX(-90deg) and opacity: 0, with transform-origin: center top: it lies flat, hooked by its top edge, like the flap of a sheet.
On click, the .open class starts two movements. The panel grows in 0.5 s on cubic-bezier(0.65, 0, 0.35, 1); the text rises from −90° to 0° in 0.4 s on a bouncy curve, 0.1 s later, and goes to opacity 1. Measured 150 ms after the click: panel at 7 px out of 66 and text still at −47° (Chromium 151), the same values within a few pixels in Firefox 153 and WebKit 26.5; everything is in place around 0.6 s. The arrow turns 180° in 0.4 s. On closing, the same path plays backwards and visibility only goes back to hidden after the 0.5 s, so the sheet stays visible while it folds.
The height comes from the script (2.3 KB), not from a fixed value: on opening, it writes the content's real height (scrollHeight) into max-height, then replaces it with none at the end of the transition. A 300 px text therefore opens in full (measured in all three engines), and an open panel follows its content when the window changes width. To close from none, it goes back through the height in pixels before returning to 0, otherwise the closing would be instant. It closes the other sections of the same list, sets aria-expanded and aria-controls (with an id created if the panel has none), and works for every .accordion-fold-container list of the page. If a list is hidden when a section opens (hidden tab), the panel goes straight to none.
Accessibility
- Keyboard and state: the headers are
<button>s — Tab reaches them, Enter or Space opens and closes. Each header announcesaria-expanded(true/false, measured) and points to its panel witharia-controls. The decorative arrow isaria-hidden. - Closed panels truly hidden:
visibility: hiddenremoves closed content from the tab order and from screen readers. Measured with a link in a closed panel: from the last header, Tab goes straight to the element after the list (Chromium, Firefox). - Reduced motion: under
prefers-reduced-motion, no fold and no height slide — the panel opens to its size at once and the text appears with a 0.15 s fade (measured in all three engines: 66 px out of 66 and 0° angle from 150 ms). - Contrast: white headers on #0a0a0f (19.8:1). The panel text, white at 60% opacity, stays around 7:1 on that background; on a light background, recolor both (the example scenes do).
Browser compatibility
CSS (perspective, rotateX, max-height and visibility transitions) + 2.3 KB of JavaScript, no dependency. Measured in Chromium 151, Firefox 153 and WebKit 26.5: same fold sequence, same real height for long content, one section open, same behavior under reduced motion. Nothing recent: 3D transforms and matchMedia have existed everywhere since well before 2018.
Without JavaScript, the headers do nothing and the panels stay closed: if the content is essential, add the open class in the HTML to the sections to show by default. Under reduced motion, the fold and the slide are replaced by a short fade.
The code
HTML structure to paste into your page (the CSS + JS come with Premium):
<div class="accordion-fold-stage">
<div class="accordion-fold-container">
<div class="accordion-fold-item">
<button class="accordion-fold-header" type="button">
<span>…</span>
<span class="accordion-fold-arrow" aria-hidden="true">▼</span>
</button>
<div class="accordion-fold-content">
<div class="accordion-fold-inner">…</div>
</div>
</div>
… (une .accordion-fold-item par rubrique)
</div>
</div>
The full HTML + CSS + JS of Accordion Fold, ready to paste — plus all 840 effects. Or $299 once, lifetime access.
Customize
Options passed to the API or data-* attributes:
| Option / property | Default | Effect |
|---|---|---|
Fold angle (CSS — rotateX(-90deg) on .accordion-fold-inner) |
−90°: text lying flat before it rises | −45° gives a subtler fold; beyond −90°, the text goes behind its edge and disappears for part of the movement. |
Perspective (CSS — perspective: 600px on .accordion-fold-content) |
600 px | 300 px emphasizes depth (the bottom of the text seems to come toward you); 1,200 px flattens the fold. |
| Durations (CSS — 0.5 s for the height, 0.4 s + 0.1 s delay for the text) | 0.5 s / 0.4 s | Keep the height a little longer than the fold, otherwise the text rises in a panel still too short. Also change the visibility 0s .5s if you change the height duration. |
Bounce (CSS — cubic-bezier(.34, 1.56, .64, 1) on the text) |
the text slightly overshoots 0° before settling | ease-out for a sober fold, suited to a leaflet or a contract. |
Several open sections (JS — the click's items.forEach loop) |
one open section per list | Remove the loop that closes the other sections to let each one open independently. |
Section open on load (HTML — open class on .accordion-fold-item) |
all closed | The script recognizes it: panel at its height, aria-expanded="true", with no animation on load. |
FAQ
height to auto (except recent Chromium with interpolate-size, missing from Firefox 153 and WebKit 26.5, measured). The script therefore measures the real height and writes it into max-height, then goes back to none once open. A fixed value (200 px for instance) would clip longer content and distort the duration: a 48 px text would travel its 48 px in a fraction of the planned 0.5 s..accordion-fold-container list, with no id to write. Closed panels are out of the tab order, so the page stays quick to browse by keyboard. For search engines, keep the text in the HTML (it is here, only hidden).