CSS Perspective Generator
Slide the values, watch a real element move, copy the CSS. perspective, perspective-origin, rotate, translateZ, scale, preserve-3d.
.scene {
perspective: 800px;
}
.card {
transform: rotateY(-30deg);
transform-style: preserve-3d;
}<div class="scene">
<div class="card">…</div>
</div> Numbers you can see
The CSS perspective generator is a set of sliders wired to a real element, so the preview is exactly what a browser will render, not a picture of it. Move perspective and watch the difference between a wide-angle 300px and a flat 2000px; move perspective-origin and watch the vanishing point slide; rotate and translate and read the CSS below. Copy it when it looks right.
How the pieces fit
perspective on a parent creates a 3D space with one vanishing point that all its children share; perspective-origin says where that point is. Each child's transform then rotates and moves it within that space: rotateY turns it like a door, rotateX tilts it like a laptop lid, rotateZ spins it flat, translateZ brings it toward the viewer (positive) or pushes it away. transform-origin sets the hinge. transform-style: preserve-3d lets the children of a transformed element keep their own 3D positions, which a cube or a stack of layers needs. backface-visibility: hidden hides an element once it has turned to show its back, which card flips rely on.
A sense of scale
Think of perspective as a lens. The pinhole model behind the perspective grids here says that a 36 mm-wide sensor with a 50 mm lens has the viewer at 50/36 of the frame width from the picture plane; for a 900px-wide scene that is about 1250px. So perspective: 1250px on a 900px-wide container looks like a normal photograph, 600px like a 24 mm wide-angle, 2500px like a 100 mm telephoto. If a 3D effect looks "off", it is usually a perspective value chosen for a different container width.
What it is good for
Tilted cards on hover, a book cover opening, a phone mockup turned in space, the title crawl, an isometric-looking dashboard illustration (large perspective plus rotateX 55° and rotateZ −45°), and flip cards. For text and images that need to be baked into a PNG rather than live, the perspective text generator and change image perspective do the same transform to pixels.
Related
Perspective text generator · change image perspective · 1-point vs 2-point vs 3-point explains the vanishing points the browser is computing.
Questions
What does the CSS perspective property do?
It sets the distance, in pixels, between the viewer and the z = 0 plane, and turns on 3D projection for the element's children. A small value (200–500px) is like a wide-angle lens: strong convergence, things near the viewer look huge. A large value (1500px and up) is a telephoto: gentle, almost flat. Without it, rotateX and rotateY just squash the element.
Should I put perspective on the parent or use perspective() in transform?
On the parent when several children should share one vanishing point, like cards in a row or the faces of a cube; that is the usual choice. perspective() inside transform gives each element its own vanishing point at its own centre and is fine for a single element.
What does perspective-origin do?
It moves the vanishing point. 50% 50% (the default) is straight in front of the element's centre; 50% 0% is as if you were looking from above; 0% 50% from the left. It only applies with perspective on the parent; the perspective() function always uses the element's centre.
Why is my rotated element clipped or flat?
A parent with overflow: hidden clips it; transform-style: flat on an intermediate element flattens 3D children; and without perspective on any ancestor there is no projection at all. For nested 3D (a cube), every element between the scene and the faces needs transform-style: preserve-3d.
What is backface-visibility?
Whether the element is drawn when rotated more than 90° so you would be seeing its back. hidden is used for card-flip effects: the front hides at 90° and a back face rotated 180° takes over.
Does this work in every browser?
perspective, 3D transforms, transform-style and backface-visibility are supported unprefixed in all current browsers. Very old WebKit needed -webkit- prefixes; only add them if you support browsers from before 2020.