Skip to content
All designer tools

3D Transform & Perspective Playground

rotateX, rotateY and the three parent properties that have to agree before any of it looks right

.scene — perspective: 800px
.cardrotateX(-12deg) rotateY(24deg)

Perspective is the distance from the viewer to the z=0 plane. Small numbers are a wide-angle lens — dramatic, distorted; large numbers flatten towards an isometric projection.

cssCSS
/* On the PARENT — this is the part that catches everyone out.
   perspective on the transformed element itself does nothing useful. */
.scene {
  perspective: 800px;
  transform-style: preserve-3d;
}

.card {
  transform: rotateX(-12deg) rotateY(24deg);
  backface-visibility: hidden;
}
htmlHTML
<div class="scene">
  <div class="card">…</div>
</div>

Now use it on something

Every effect, block, page and template in the catalog is styled against tokens shaped exactly like these — so they take your values rather than fighting them.

Hand these tokens to an agent

npx shadcn@latest add https://hoverlab.dev/r/hoverlab.json

perspective800px

How far the viewer is from the z=0 plane. This is the property that has to live on the parent — set it on the element you are rotating and you get a flat squash instead of depth. Under about 400px it reads as a fisheye; over about 1500px it barely reads at all.

perspective-origin X50%

Where the viewer is standing, horizontally. Moving it off centre is how you get a scene that looks lit and composed rather than photographed head-on.

perspective-origin Y50%

The same, vertically. Below 50% you are looking down at the scene; above, up at it.

Keeps children in the same 3D space as their parent. Off — the default, `flat` — every child is projected onto the parent's plane first, which is exactly why a card flip built from two faces shows both of them at once.

rotateX-12deg

Tips the element towards or away from you, around the horizontal axis. Small negative values — the top leaning back — are the standard product-shot angle.

rotateY24deg

Turns it around the vertical axis. At exactly 180 you are looking at the back, which is where backface-visibility starts to matter.

rotateZ0deg

A flat spin in the plane of the screen — the same thing plain `rotate` does. No perspective is involved, so this one looks identical whatever the scene is set to.

translateZ0px

Moves the element towards the viewer or away. This is the one that needs perspective to do anything visible at all — with no perspective on the parent it is a no-op, which is the fastest way to confirm the scene is set up correctly.

translateX0px

Horizontal move, applied before the rotations so the element turns around where it ended up.

translateY0px

Vertical move.

scale1

Uniform resize. Applied last in the list, so it scales the already-rotated result rather than the original box.

skewX0deg

Shears horizontally. Genuinely 2D — no amount of perspective makes a skew look three-dimensional, which is worth knowing before you spend an afternoon trying.

skewY0deg

Shears vertically.

transform-origin X50%

The pivot, horizontally. Moving it to an edge is the difference between a card spinning in place and a door swinging open.

transform-origin Y50%

The pivot, vertically. Bottom-centre is the hinge a dropdown wants; top-centre is the one a tooltip wants.

Hides the element once it has turned more than 90° away. Set rotateY past 90 with this off to see the mirrored back — and then understand why every card flip on the web sets it.

Swaps the single face for the two-sided card everyone is actually trying to build when they find rotateY. The copied CSS becomes the whole recipe — both faces, the transition, and the reduced-motion guard.

Keep this transform. This browser remembers what you last had open. A free account remembers the ones you name, on every machine you use.

More designer tools

All 36 run in the tab — no account, no upload.See all