Door Open Effect
A 150 × 180 px door hinged on the left swings 110° in 0.6 s and comes toward you, revealing what it was hiding in its frame; once open, you see its back. Hover, Tab or a tap open it, with no JavaScript; under reduced motion, it fades out instead of swinging.
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-0014-root (#0a0a0f background, at least 300 px tall) centers the frame .door-container: 150 × 180 px, position: relative, perspective: 1000px and tabindex="0". Inside, two blocks are stacked: .door-content, the content behind the door (#1a1a2e background, #6366f1 text), then .door, the door itself (#6366f1 → #4f46e5 gradient), kept on top by z-index: 2. The door turns around its left edge (transform-origin: left center), as on its hinges.
When the frame is hovered, or has focus (:focus-within), the door gets rotateY(-110deg) over 0.6 s: it passes perpendicular around 0.3 s and stops 20° further, its free edge come toward you. As it comes closer, perspective enlarges it: measured in Chromium 151, the open door covers 72 px to the left of the hinge and 210 px in height, 15 px above and below the frame. Its back is not hidden: you see the back of the door, with its label mirrored, like the back of a real door.
Two choices hold the effect together. The hover sits on the frame, which does not move: its 150 × 180 px area stays stable while the door turns, and the open door, being one of its children, keeps the hover if the pointer moves onto it. And the door opens outside its frame, to the left: leave about 80 px free on that side, or it swings over the neighboring element (which is intended in the first scene above, where three doors follow each other down a hallway).
Accessibility
- Keyboard and touch: the frame has
tabindex="0"and the:hoverrule is doubled by:focus-within. Tab opens the door, the next Tab closes it; a 2 px#a5b4fcring (:focus-visible) marks keyboard focus. On a touchscreen, a tap opens it, a tap elsewhere closes it. Measured in Chromium 151, Firefox 153 and WebKit 26. A mouse click also gives focus: the door stays open until the next click elsewhere. - Reduced motion: under
prefers-reduced-motion: reduce, a block scoped to.fx-0014-rootremoves the rotation (computed transform:none); the door fades out over 0.3 s and leaves what it was hiding readable, with nothing sticking out of the frame. - What the door hides: only on screen. The content of
.door-contentis in the HTML, before the door: screen readers read it first, door open or closed. - Contrast: 16 px semibold text. On the door, white measures 4.47:1 to 6.29:1; behind it,
#6366f1on#1a1a2ereaches only 3.82:1. Use#818cf8(5.72:1) or#a5b4fc(8.56:1) if the hidden content carries information.
Browser compatibility
CSS only (perspective, rotateY, transform-origin, :focus-within, :focus-visible), no JavaScript, no dependencies. Measured in Chromium 151 and Firefox 153: same opening, same overflow to the left, two independent copies on one page, fade without rotation 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 door stays closed and covers its content. 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-0014-root">
<div class="demo-3d">
<div class="door-container" tabindex="0">
<div class="door-content">… derrière la porte …</div>
<div class="door">… façade …</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 |
|---|---|---|
Opening angle (CSS — rotateY(-110deg) in the hover rule) |
−110° | -90deg stops the door side-on: only its edge shows. -70deg leaves it ajar. Beyond −130°, it folds back toward the wall and overflows more. |
Hinge side (CSS — transform-origin and sign of the angle) |
left center, −110° | For a door opening to the right: transform-origin: right center and rotateY(110deg). It still comes toward you and then overflows on the right. |
| Opening direction (CSS — sign of the angle) | toward you | rotateY(110deg) with the hinge on the left sends the door into the screen: it shrinks instead of growing, and its overflow to the left is shorter. |
Perspective (CSS — perspective of .door-container) |
1000px | Smaller, the door grows more as it opens and overflows further. For a large door (300 px wide), go to 1,800 px or more so it stays inside the page. |
Size and duration (CSS — .door-container, transition of .door) |
150 × 180 px, .6s | The door and the content follow the frame (100%). .9s gives a heavy wardrobe door, .4s a light swing door. |
Colors and focus ring (CSS — .door, .door-content, :focus-visible) |
#6366f1 → #4f46e5, #1a1a2e / #6366f1, ring #a5b4fc | Give the content a background clearly darker than the door: it is the shadow of the interior. On a white page, pick a dark ring. |
FAQ
<span>) with backface-visibility: hidden and transform: translateZ(1px), and give the door transform-style: preserve-3d: the text disappears as the door passes perpendicular and the back keeps the door's color. Measured in Chromium and Firefox; without translateZ, Firefox keeps the text visible.rotateY(110deg).transform-origin: right center and rotateY(110deg). Both leaves open toward you, each on its own side. Each copy has its own hover area: to open both together, move the hover rule to a shared parent.