Free · Fast · Privacy-first

CSS 3D Transform

CSS 3D transforms use a three-dimensional coordinate system to rotate, translate, and scale elements in depth.

Supports rotateX, rotateY, rotateZ, translateZ, and scale3d

🔒

Perspective control with real-time depth preview

transform-style: preserve-3d container setup

Backface-visibility toggle for card flip and cube faces

Cost
Free forever
Sign-up
Not required
Processing
In your browser
Privacy
Files stay local
FreeNo signupWhite-label

Add this Transform Gen to your website

Drop the Transform Gen into any page — blog post, product docs, intranet, school portal — with a single line of HTML. Your visitors get the full tool, processed entirely in their browser. No backend, no uploads, no signup.

  • Files stay 100% in the visitor's browser
  • Responsive — adapts to any container width
  • Free forever, no API key needed

Embed code

<iframe
  src="https://www.fixtools.io/css-tool/transform-gen?embed=1"
  width="100%"
  height="780"
  frameborder="0"
  style="border:0;border-radius:16px;max-width:900px;"
  title="Transform Gen by FixTools"
  loading="lazy"
  allow="clipboard-write"
></iframe>

Attribution-friendly: a small "Powered by FixTools" link appears in the embed footer.

CSS 3D Transform Setup: Perspective, preserve-3d, and Building a 3D Cube

A 3D transform on its own produces no visible depth effect without a perspective context. The perspective property on the parent element defines the distance from the viewer to the z=0 plane. A value of 400px means the viewer is conceptually 400px from the screen. Elements with positive translateZ values appear larger because they are closer to the viewer than the z=0 plane; elements with negative translateZ appear smaller. The perspective value controls how dramatic the depth distortion is: small values like 200px produce extreme foreshortening that looks exaggerated, while large values like 1200px produce subtle depth that reads more as a gentle tilt than true 3D. Most UI 3D effects use perspective values between 400px and 800px.

The transform-style: preserve-3d property on a container element instructs the browser to render child elements in the same three-dimensional space as the container instead of flattening them. Without preserve-3d, each child's 3D transforms are computed in isolation and then flattened to a 2D plane before compositing. With preserve-3d, children can be positioned at different Z depths and rotations and will correctly occlude and appear in front of or behind each other based on depth. This property is essential for building multi-face 3D objects like cubes, cylinders, and carousels where faces need to exist in shared 3D space.

A CSS 3D cube requires six face elements inside a container with transform-style: preserve-3d. Each face is absolutely positioned and translated or rotated to its correct position in 3D space. The front face needs translateZ(half-cube-width), the back face needs translateZ(-half-cube-width) and rotateY(180deg), the left and right faces need rotateY(90deg) and rotateY(-90deg) with translateZ applied, and the top and bottom faces need rotateX(90deg) and rotateX(-90deg). The container is rotated with rotateX and rotateY values to reveal different faces. backface-visibility: hidden on each face prevents faces that point away from the viewer from showing through the front faces.

3D transforms are the heaviest transform category from a GPU memory perspective. Every element inside a preserve-3d container becomes its own compositor layer because the browser cannot flatten them ahead of compositing. A six-face cube at 400 pixels per side consumes roughly 4 MB of GPU memory before any animation runs, and that figure doubles on retina displays where each pixel is rasterized at 2x. Chrome DevTools Performance and Layers panels expose the actual memory usage and let you confirm that layer count stays within budget. Avoid putting more than a few dozen 3D-transformed elements on screen at once on mobile devices, where total GPU texture budget can be as low as 64 MB on entry-level Android phones, and tear down preserve-3d containers when their animations complete to release the layers.

How to use this tool

💡

Set a perspective value on the parent container, then add 3D transform functions: rotateX, rotateY, rotateZ, or translateZ. Toggle transform-style: preserve-3d to see child elements share 3D space. Adjust perspective-origin to change the vanishing point. Copy the full CSS including container and element rules.

How It Works

Step-by-step guide to css 3d transform:

  1. 1

    Set perspective on the container

    Enter a perspective value in the parent container field. Start with 600px and adjust based on how dramatic the depth effect should appear.

  2. 2

    Add 3D transform functions

    Select rotateX, rotateY, rotateZ, or translateZ from the function list. Set values and watch the preview element move in three-dimensional space.

  3. 3

    Enable preserve-3d for multi-face objects

    Toggle transform-style: preserve-3d on the container to place children in shared 3D space. Add backface-visibility: hidden to face elements that should disappear when rotated away from the viewer.

  4. 4

    Copy the full CSS

    Click Copy Code to export all generated CSS including container perspective, transform-style, and element transform declarations. Paste into your stylesheet.

Real-world examples

Common situations where this approach makes a real difference:

3D card flip on hover

A service card needs a flip animation that reveals a back face with a call-to-action when hovered. The container gets perspective: 600px. The card wrapper gets transform-style: preserve-3d and transition: transform 600ms ease. The front face is position: absolute with backface-visibility: hidden. The back face is position: absolute, rotateY(180deg), and backface-visibility: hidden. On hover the card wrapper receives rotateY(180deg). The generator outputs all four declarations with correct values.

Product 360-degree viewer

An e-commerce detail page shows a product that can be rotated in 3D by dragging. The product image container has transform-style: preserve-3d and perspective: 800px on its parent. JavaScript reads mousemove events and applies rotateY and rotateX values to the container. The generator is used to test which perspective value produces a realistic depth appearance for the product image dimensions before writing the drag interaction code.

Animated CSS cube loader

A loading state uses an animated CSS cube that rotates continuously. Six face divs are positioned using the translateZ-and-rotate technique. The container rotates with @keyframes that cycle through rotateY(0deg) rotateX(0deg) to rotateY(360deg) rotateX(360deg) over 4 seconds using linear timing. The generator is used to calculate the correct translateZ for the face size, and backface-visibility: hidden is set on all faces.

3D page-turn effect for a portfolio

A portfolio section uses a 3D page-turn animation where clicking a project card rotates it rotateY(180deg) around its right edge with transform-origin: right center. The perspective on the parent is set to 900px for a subtle depth that reads as a page turn rather than a flat flip. The back face reveals project details. backface-visibility: hidden on both faces ensures clean transitions without see-through artifacts.

Pro tips

Get better results with these expert suggestions:

1

Match cube translateZ to half the cube side length

For a 200px cube, each face needs translateZ(100px) before the axis rotation that places it in position. This centers the face on the cube surface. If you use a different value, the cube will look stretched or compressed on the axis. The formula is: translateZ = container-side-length / 2. The generator calculates this automatically when you enter the cube dimensions.

2

Use perspective-origin to shift the vanishing point

The perspective-origin property defaults to 50% 50%, placing the vanishing point at the center of the container. Shifting it to 0% 0% moves the vanishing point to the top-left corner, creating an isometric-style depth effect. Shifting it beyond the container boundaries creates extreme perspective angles that can look cinematic for hero animations. Adjust perspective-origin alongside the perspective value to tune the exact depth appearance.

3

Avoid mixing 2D and 3D transforms on the same element

Applying a 2D transform like rotate(45deg) alongside a 3D transform like rotateY(30deg) on the same element can produce unexpected results because the browser resolves them into a single matrix. Use only 3D variants, rotateZ(45deg) instead of rotate(45deg), when working in a 3D transform context to ensure the coordinate system is consistent and the matrix computation is predictable.

4

Animate rotateY on a preserve-3d container for 3D carousels

A 3D card carousel works by placing cards around the Y axis at regular rotateY intervals (360 divided by card count), each with a translateZ equal to the carousel radius. The container has transform-style: preserve-3d and perspective set on its parent. Animating the container's rotateY brings different cards to the front. The generator can output the initial transform values for each card position if you enter the card count and radius.

5

Set perspective on the parent, not on the element itself

The CSS perspective property belongs on the parent element. This creates a single shared vanishing point for all children. If you use the perspective() function inside an element's own transform list, each element gets its own independent perspective, so multiple elements in the same container do not share depth. For any 3D scene with multiple elements, use the perspective property on the container.

6

Use backface-visibility: hidden on all cube faces

Without backface-visibility: hidden, faces of a 3D object that are rotated more than 90 degrees from the viewer remain visible as mirror-image outlines showing through the front faces. Setting backface-visibility: hidden makes each face invisible when it faces away from the viewer, which is the correct behavior for solid 3D objects.

7

Test 3D effects on Safari with WebKit prefix fallback

Safari on older iOS versions requires -webkit-transform-style: preserve-3d and -webkit-backface-visibility: hidden. Modern Safari 15 and later supports the unprefixed forms, but iOS 14 devices still in circulation need the prefixed versions. Add both prefixed and unprefixed declarations when supporting older Safari.

FAQ

Frequently asked questions

Without perspective, the browser uses orthographic projection to display 3D transforms. In orthographic projection, all depth information is lost: a point at Z=0 and a point at Z=200px map to the same 2D screen position. A 90-degree rotateY collapses the element to a vertical line because all points are projected at the same X position. Adding perspective: 600px to the parent switches to perspective projection, where closer points appear larger and the illusion of depth is created.
By default, the browser flattens an element's 3D-transformed children into a 2D plane before compositing them. Setting transform-style: preserve-3d on a container tells the browser to render children in actual 3D space, allowing them to appear in front of or behind each other based on their Z positions and rotations. This property is required for any 3D object with multiple faces, such as a cube, carousel, or flip card. Without it, faces will all render at the same depth regardless of their transform values.
The backface-visibility property controls whether an element is visible when it is rotated more than 90 degrees away from the viewer, meaning its back face is facing the screen. The default value visible means the back face is rendered as a mirror image of the front. Setting backface-visibility: hidden makes the element invisible in this state. Use it on all faces of a 3D card flip or cube to prevent the reverse side of each face from being visible through the front faces of the object.
Create a container with transform-style: preserve-3d and perspective on its parent. Create six child face elements positioned absolutely inside the container. Translate and rotate each face: front gets translateZ(half-size), back gets rotateY(180deg) translateZ(half-size), left gets rotateY(-90deg) translateZ(half-size), right gets rotateY(90deg) translateZ(half-size), top gets rotateX(90deg) translateZ(half-size), bottom gets rotateX(-90deg) translateZ(half-size). Set backface-visibility: hidden on all faces. Rotate the container to show different faces.
For card flip effects, a perspective value between 600px and 1000px produces a realistic flip that reads as a physical card without looking exaggerated. Smaller values like 200px create an extreme fish-eye effect where the card appears to warp dramatically as it rotates. Larger values like 2000px reduce the depth effect to the point where the flip looks almost flat. The right value depends on the card size: smaller cards need lower perspective values proportionally to produce the same visual depth impression.
3D transforms are supported on all modern mobile browsers including Safari on iOS and Chrome on Android. Safari on iOS has historically required the -webkit-transform-style: preserve-3d prefix for older versions. Current iOS Safari 15 and later supports the unprefixed form. For maximum compatibility on devices that may be running older iOS versions, include both the prefixed and unprefixed forms of transform-style and backface-visibility in your CSS.
Yes, but with limitations. Each element with transform-style: preserve-3d creates its own 3D rendering context, and these contexts do not merge into a single shared space. A deeply nested element participates in its direct parent's 3D space but not in a grandparent's space. Some browsers also do not correctly support nested preserve-3d contexts, particularly older Safari versions. For complex scenes, keep the 3D hierarchy as flat as possible and nest all faces directly inside a single preserve-3d container.
perspective-origin defines the X and Y position of the viewer's eye relative to the perspective container. The default is 50% 50%, which places the vanishing point at the container center. Changing it to 0% 50% moves the vanishing point to the left edge, creating a view as if the viewer is looking from the left. Changing it to 100% 0% places the viewer at the top-right corner. This property gives fine control over the viewing angle in a 3D scene without changing the rotation of the elements themselves.
Wrap 3D rotation animations in @media (prefers-reduced-motion: no-preference) so the animation only runs when the user has not requested reduced motion. For users who have, replace the 3D rotation with an instant state change or a simple opacity crossfade between the front and back faces. 3D rotations are among the most disorienting motion types for users with vestibular sensitivity because the apparent geometry of the element changes continuously. A static crossfade conveys the same state change without inducing discomfort. Test the fallback by enabling Reduce Motion in macOS System Settings or iOS Accessibility settings before shipping.
A common cause is an intermediate element between the preserve-3d container and the 3D children that has overflow: hidden, opacity below 1, a filter, or a mask. Any of these properties forces the intermediate element to flatten its descendants, breaking the 3D rendering context even though preserve-3d is declared elsewhere. The MDN compatibility table calls this out as a grouping property side effect. The fix is to remove the offending property from the intermediate element, restructure the markup so the 3D children are direct descendants of the preserve-3d container, or accept that the children will be flattened and adjust the design accordingly to keep the visual hierarchy and depth cues working as the designer intended.

Related guides

More use-case guides for the same tool:

Ready to get started?

Open the full Transform Gen — free, no account needed, works on any device.

Open Transform Gen →

Free · No account needed · Works on any device