Tools / Type & web

CSS Perspective Generator

Slide the values, watch a real element move, copy the CSS. perspective, perspective-origin, rotate, translateZ, scale, preserve-3d.

perspective: 800pxrotateY(-30°) rotateX(0°)A card with text, a border and a shadow. Drag the sliders; the CSS below updates.
live DOM preview — what the browser will actually render
Perspective
Rotate
Move & scale
Element
Vanishing point at 50% 50%Distance 800 px ≈ normal
CSS
.scene {
  perspective: 800px;
}

.card {
  transform: rotateY(-30deg);
  transform-style: preserve-3d;
}
HTML
<div class="scene">
  <div class="card">…</div>
</div>
Draw more, set up less

That grid took you a minute. Forty-six are already drawn.

Every lens from 24 to 85 mm and every camera height, as true vector sheets for A4, A3, Letter and Tabloid — print one and start drawing. The same 46 grids come as transparent layers for Procreate, Photoshop, Clip Studio and Krita. 252 finished scenes to draw straight over, each one carrying the camera that made it. And thirty exercises that teach the whole thing, each with its construction worked on the next page. Every one has a free starter, so you can try the real files first.

Free starters: seven sheets, twenty scenes, five exercises. The three grid-and-reference packs together are $24, seven less than the parts. The printable templates and the reference library stay free whatever you do — a pack sold is what keeps them that way.

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.

More tools

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.