Skip to content
perspective / transformAdvancedUsed in 227 effects

Perspective and CSS 3D transforms

CSS transforms can move elements along the z-axis and rotate them around three-dimensional axes. Perspective projects that virtual depth onto a flat screen: nearby surfaces appear larger, distant surfaces smaller, and rotations gain believable foreshortening.

A reliable scene separates the camera, the 3D object, and its faces. That structure prevents transforms from fighting each other and makes hover, focus, and reduced-motion behavior easier to control.

Separate the scene, object, and faces

Put perspective on a parent scene. Add transform-style: preserve-3d to the object whose children should retain z-depth. Position and rotate individual faces inside that object.

A smaller perspective distance creates stronger distortion; a larger value looks flatter. Start around 800–1200px for interface cards and adjust according to the object's size.

perspective
Defines the camera distance for transformed descendants.
transform-style
Keeps child transforms in a shared 3D space when set to preserve-3d.
backface-visibility
Hides the reverse side of a rotated surface in card-flip patterns.
cssA two-sided card foundation
.scene { perspective: 900px; }
.card {
  position: relative;
  transform-style: preserve-3d;
  transition: transform 600ms cubic-bezier(.2,.7,.2,1);
}
.card.is-flipped { transform: rotateY(180deg); }
.card__face {
  position: absolute;
  inset: 0;
  backface-visibility: hidden;
}
.card__back { transform: rotateY(180deg); }

Property perspective versus perspective()

The perspective property gives sibling objects one shared camera and vanishing point. The perspective() transform function applies perspective inside a single element's transform list, so each element can appear to have its own camera.

Transform functions are applied in order and do not generally commute. perspective() rotateY() translateZ() can produce a different result from the same functions rearranged. Keep a documented order and test from the final interaction states.

Avoid accidental flattening

Some grouping properties flatten descendants even when preserve-3d is present. Clipping, filtering, and certain opacity or blending combinations can collapse the scene into the parent's plane.

If a scene must also clip rounded corners, add a separate outer wrapper for clipping and keep the 3D object inside it. Separating responsibilities is more dependable than stacking every effect on one box.

Design readable, controllable motion

Large rotations can make text blurry or hard to track. Keep text near its resting plane, avoid tiny type on angled surfaces, and provide a non-animated state under reduced-motion preferences.

Do not make important content available only on hover. A flip card should also respond to keyboard activation and expose its state through an actual button or other semantic control.

cssA calmer fallback
@media (prefers-reduced-motion: reduce) {
  .card { transition: opacity 160ms ease; transform: none; }
  .card__back { transform: none; }
}

Live catalog examples

These production examples use perspective / transform. Open any effect to inspect its complete source and experiment in the browser editor.

Browser support

Support notes refer to stable, unprefixed behavior unless a prefix is explicitly listed.

FeatureBrowsersNote
3D transforms / perspectiveAll modern browsersCurrent versions do not require prefixes.
transform-style: preserve-3dAll modern browsersGrouping properties can still force descendants to flatten.
backface-visibilityAll modern browsersTest antialiasing and focus behavior on both faces.

Common pitfalls

  • rotateY is used without perspective

    Add a camera with parent perspective or the perspective() transform function.

  • preserve-3d is missing

    Apply it to the object whose transformed children must share depth.

  • Transform functions are reordered

    Order changes the coordinate system and therefore the final geometry.

  • Clipping and 3D live on the same element

    Use separate wrappers so rounded clipping does not unexpectedly flatten the scene.

Frequently asked questions

What perspective value should I use?
Start around 800–1200px for card-sized UI. Smaller values exaggerate depth; larger values flatten it.
Why can I see mirrored text?
The back face is visible. Add `backface-visibility: hidden` to each face.
Why are my children still flat?
Check `transform-style: preserve-3d` and look for an ancestor property that forces flattening.
Are 3D transforms accessible?
They can be when content remains semantic, interactions work without hover, and reduced-motion users receive a stable alternative.

Related guides

Last updated:

All guides