Folding Panel
A 200 × 120 px panel cut in two: the top half, like a flap, tips toward you around the center line in 0.6 s and vanishes halfway, uncovering a magenta half hidden underneath; the bottom half stays still. Hover, Tab or a tap lift it, with no JavaScript; no rotation (the flap fades out) when the user reduces motion.
Updated
This effect is part of Effect.Labs — 840 vanilla effects, some free, some premium. 3D has 50 effects, including 8 free. Explore the category →
3 usage examples



How it works
The root .fx-0005-root (#0a0a0f background, at least 300 px tall) centers a 200 × 120 px .fold-container frame, with perspective: 800px and tabindex="0". Inside, .fold-panel (transform-style: preserve-3d) stacks three blocks with position: absolute. In HTML order: .fold-reveal, the hidden top half (#d946ef → #a855f7 gradient); .fold-top, the flap covering it (#6366f1 → #4f46e5 gradient), painted on top because it comes later; .fold-bottom, the fixed bottom half (#4f46e5 → #3730a3 gradient).
The flap turns around its bottom edge (transform-origin: center bottom), which is the center line of the panel. When the frame is hovered, or has focus (:focus-within), it gets rotateX(-180deg) over 0.6 s: its top edge comes toward you and down. It has backface-visibility: hidden, so it disappears as soon as it passes the vertical, around 0.18 s (181 ms measured in Chromium 151), and finishes its course invisible, lying over the bottom half. You see the flap lift toward you, then fade from view, and the hidden half appear in its place.
Why the back face is hidden: without backface-visibility: hidden, the back of the flap would stay on screen once turned, lying over the bottom half, with its text upside down on top of the fixed text. Why the hover sits on the frame: the flap changes shape while it turns (at 90° it is just a line); the frame keeps a fixed 200 × 120 px area, and the panel does not close as long as the pointer stays on it.
Accessibility
- Keyboard and touch: the frame has
tabindex="0"and the:hoverrule is doubled by:focus-within. Tab lifts the flap, the next Tab closes it; a 2 px#a5b4fcring (:focus-visible) marks keyboard focus. On a touchscreen, a tap lifts it, a tap elsewhere closes it. Measured in Chromium 151, Firefox 153 and WebKit 26. A mouse click also gives focus: the flap stays up until the next click elsewhere. - Reduced motion: under
prefers-reduced-motion: reduce, a block scoped to.fx-0005-rootremoves the tipping (computed transform:none); the flap fades out over 0.3 s (opacity 0) and leaves the hidden half readable. - What the flap hides: it hides on screen, not in the page. The text of
.fold-revealis in the HTML, read first by screen readers (it comes before the flap) and visible in the page source. Perfect for a number or a code that already belongs to the person looking; never for data that truly needs protecting. - Contrast: 16 px semibold white text. Flap: 4.47:1 to 6.29:1; bottom half: 6.29:1 to 9.93:1; hidden half: 3.46:1 to 3.96:1, below the 4.5:1 threshold. Darken the hidden half (for instance
#c026d3→#7c3aed, 4.71:1 and 5.70:1) if it carries information.
Browser compatibility
CSS only (perspective, transform-style: preserve-3d, backface-visibility, :focus-within, :focus-visible), no JavaScript, no dependencies. Measured in Chromium 151 and Firefox 153: same tipping, same vanishing halfway, two independent copies on one page, fade without tipping under reduced motion. Playwright's WebKit (26.5) flattens all CSS 3D, even a reference cube: focus and touch are measured there, the 3D rendering was not checked on a real Safari.
Without 3D transforms, the flap does not move and keeps covering the hidden half. In Safari before 15.4, add -webkit-backface-visibility: hidden to the flap, otherwise its back stays visible, upside down, over the bottom half. Without :focus-visible, the browser's default focus outline shows instead.
The code
HTML structure to paste into your page (the CSS + JS come with your purchase):
<div class="fx-0005-root">
<div class="demo-3d">
<div class="fold-container" tabindex="0">
<div class="fold-panel">
<div class="fold-reveal">… caché sous le rabat …</div>
<div class="fold-top">… rabat …</div>
<div class="fold-bottom">… moitié fixe …</div>
</div>
</div>
</div>
</div>
One-time payment, no subscription — the code is yours forever
Customize
Options passed to the API or data-* attributes:
| Option / property | Default | Effect |
|---|---|---|
Size (CSS — width and height of .fold-container) |
200 × 120 px | The three blocks are 100% wide and 50% tall: they follow the frame. Above 300 px tall, raise the perspective too (1,200 px) to keep a natural tip. |
Perspective (CSS — perspective of .fold-container) |
800px | Smaller, the flap's edge grows more as it comes toward you (500px: strong effect); larger, the tip flattens. |
Duration (CSS — transition of .fold-top) |
.6s (ease curve) | The flap disappears at about 30% of the duration, when it passes the vertical. 1s leaves time to see the gesture; .4s makes a sharp reveal. |
Tipping direction (CSS — rotateX(-180deg) in the hover rule) |
−180°: the flap comes toward you | rotateX(180deg) sends it backward, into the screen: a lid opening rather than a label being lifted. |
Flap height (CSS — height of .fold-top, .fold-reveal and .fold-bottom) |
50% each | For a one-third flap, give 33% to the flap and the hidden half, 67% to the fixed part: the flap still turns on its bottom edge. |
Colors and focus ring (CSS — gradients of the three blocks, :focus-visible) |
#6366f1 → #4f46e5, #d946ef → #a855f7, #4f46e5 → #3730a3, ring #a5b4fc | Change the gradients freely; keep the hidden half clearly different from the flap, it is what gets uncovered. On a white page, pick a dark ring. |
FAQ
backface-visibility: hidden: past the vertical, its back would face the screen, and that back is not drawn. Without that rule, you would see the flap lying on the bottom half with its text upside down. For a flap that visibly lands, give it a child with position: absolute; inset: 0 turned 180° (transform: rotateX(180deg)), with its own background and backface-visibility: hidden, give the flap transform-style: preserve-3d and stop its course at rotateX(-178deg): at exactly −180°, its back would sit in the same plane as the bottom half and slip under it (measured in Chromium and Firefox). The back then covers the bottom half.