CSS rotate3d() Function

The CSS rotate3d() function rotates an element around a specified axis in three-dimensional space.

It is used with the transform property and accepts three numbers that define the rotation axis, followed by an angle. The function can rotate elements around the X, Y, or Z axis, or around an axis combining multiple directions.

Syntax

transform: rotate3d(x, y, z, angle);

The first three arguments define the direction of the rotation axis. The fourth specifies the rotation angle.

For example:

transform: rotate3d(1, 0, 0, 45deg);
transform: rotate3d(0, 1, 0, 45deg);
transform: rotate3d(0, 0, 1, 45deg);
transform: rotate3d(1, 1, 0, 45deg);
transform: rotate3d(1, 1, 1, 60deg);

The function uses commas to separate its four arguments.

It returns a CSS <transform-function> value that can be used within the transform property.

Parameters

The rotate3d() function requires four arguments.

Parameter Description
x A number defining the X component of the rotation axis.
y A number defining the Y component of the rotation axis.
z A number defining the Z component of the rotation axis.
angle An angle specifying the amount of rotation using deg, rad, grad, or turn.

For example:

transform: rotate3d(1, 1, 0, 45deg);

This rotates the element 45 degrees around an axis combining the X and Y directions.

The axis values are unitless numbers. They can be positive, negative, or zero, but they must not all be zero.

How It Works

The rotate3d() function rotates an element around an axis passing through its transform origin.

The axis is represented by a three-dimensional vector:

rotate3d(x, y, z, angle)

The browser normalizes the axis vector, so its direction matters rather than its overall length.

For example, these declarations produce the same rotation:

transform: rotate3d(1, 1, 0, 45deg);
transform: rotate3d(2, 2, 0, 45deg);

Both vectors point in the same direction.

The rotation changes the element's visual orientation without changing the space reserved for it in the document layout.

Without perspective, some three-dimensional rotations can appear flattened because the browser displays the result on a two-dimensional screen.

Rotation Axes

The X, Y, and Z values determine which axis the element rotates around.

Axis Example Effect
X rotate3d(1, 0, 0, 45deg) Rotates around the horizontal X axis.
Y rotate3d(0, 1, 0, 45deg) Rotates around the vertical Y axis.
Z rotate3d(0, 0, 1, 45deg) Rotates within the screen plane, like a 2D rotation.
Combined rotate3d(1, 1, 0, 45deg) Rotates around a diagonal axis in 3D space.

The following declarations demonstrate the relationship between the 3D rotation functions:

transform: rotate3d(1, 0, 0, 45deg);
transform: rotateX(45deg);

transform: rotate3d(0, 1, 0, 45deg);
transform: rotateY(45deg);

transform: rotate3d(0, 0, 1, 45deg);
transform: rotateZ(45deg);

Each pair produces the same rotation.

Use rotate3d() when the rotation axis needs to combine multiple directions.

Angle Units

The rotation angle supports the standard CSS angle units.

Unit Description Full Rotation
degDegrees360deg
radRadiansApproximately 6.283185rad
gradGradians400grad
turnRevolutions1turn

For example:

transform: rotate3d(1, 0, 0, 90deg);
transform: rotate3d(1, 0, 0, 0.25turn);
transform: rotate3d(1, 0, 0, 100grad);

These declarations represent the same quarter-turn rotation around the X axis.

Positive angles follow the right-hand rule around the specified axis. Negative angles reverse the rotation direction.

For example:

transform: rotate3d(0, 1, 0, 45deg);
transform: rotate3d(0, 1, 0, -45deg);

The two declarations rotate in opposite directions around the Y axis.

Combined Rotation Axes

Using more than one nonzero axis component creates a rotation around an axis that is not aligned with a single coordinate direction.

For example:

.box {
  transform: rotate3d(1, 1, 0, 45deg);
}

This rotates the element around an axis extending diagonally between the X and Y directions.

Another example:

.box {
  transform: rotate3d(1, 1, 1, 60deg);
}

All three axis components contribute to the direction of rotation.

Negative components can also be used:

.box {
  transform: rotate3d(1, -1, 0, 45deg);
}

This changes the direction of the axis and therefore changes the resulting orientation.

A single rotate3d() transformation is not generally equivalent to applying separate X, Y, and Z rotations using the same angle.

Perspective

Perspective makes three-dimensional rotations appear more realistic by making parts of an element appear closer or farther away.

The perspective property can be applied to a parent element:

.scene {
  perspective: 600px;
}
.box {
  transform: rotate3d(1, 1, 0, 45deg);
}

The parent provides perspective for its transformed children.

Perspective can also be specified as a transform function:

.box {
  transform: perspective(600px) rotate3d(1, 1, 0, 45deg);
}

Both approaches can create depth, but they are not interchangeable in every layout because the perspective property establishes a shared perspective for child elements.

Smaller positive perspective distances produce a stronger depth effect, while larger distances produce a flatter appearance.

For example:

.strong-perspective {
  transform: perspective(250px) rotate3d(1, 1, 0, 45deg);
}
.subtle-perspective {
  transform: perspective(1000px) rotate3d(1, 1, 0, 45deg);
}

The first declaration produces a more pronounced perspective effect than the second.

Transform Origin

The transform-origin property defines the point through which the rotation axis passes.

By default, the origin is the center of the element.

For example:

.box {
  transform: rotate3d(1, 1, 0, 45deg);
  transform-origin: center;
}

The origin can be moved using position keywords, percentages, lengths, or an optional Z-axis offset.

For example:

.top-left {
  transform: rotate3d(1, 1, 0, 45deg);
  transform-origin: top left;
}
.custom-origin {
  transform: rotate3d(1, 1, 0, 45deg);
  transform-origin: 25% 75%;
}
.depth-origin {
  transform: rotate3d(1, 1, 0, 45deg);
  transform-origin: center center 40px;
}

The third value of transform-origin specifies a length along the Z axis. Percentages are not permitted for this third value.

Changing the transform origin affects how the element moves around its rotation axis.

Preserving 3D Space

The transform-style property controls whether an element's children are positioned in three-dimensional space or flattened into the parent's plane.

For example:

.scene {
  perspective: 700px;
}
.group {
  transform-style: preserve-3d;
  transform: rotate3d(1, 1, 0, 35deg);
}
.group-child {
  transform: translateZ(50px);
}

The preserve-3d value allows transformed descendants to retain their three-dimensional positions.

The default value, flat, flattens descendants into the element's plane.

Some CSS properties, including certain clipping and opacity settings, can force flattening even when preserve-3d is specified.

For a single rotated element without transformed descendants, transform-style: preserve-3d is usually unnecessary.

Combining Transforms

The rotate3d() function can be combined with translation, scaling, and other transform functions.

For example:

.box {
  transform: perspective(600px) translateZ(30px) rotate3d(1, 1, 0, 45deg);
}

This combines perspective, movement along the Z axis, and rotation around a diagonal axis.

The order of transform functions matters.

For example:

.first {
  transform: translateX(50px) rotate3d(0, 1, 0, 45deg);
}
.second {
  transform: rotate3d(0, 1, 0, 45deg) translateX(50px);
}

These declarations generally produce different results because the transformations are combined in different orders.

Transform functions are represented by matrices and composed in their listed order. In practical terms, later transformations operate within coordinate systems affected by the earlier composition.

rotate() vs. rotate3d()

The rotate() and rotate3d() functions both rotate elements, but they differ in how the rotation axis is defined.

Feature rotate() rotate3d()
Rotation type 2D 3D
Arguments One angle Three axis numbers and one angle
Rotation axis Z axis Any valid 3D axis
Example rotate(45deg) rotate3d(1, 1, 0, 45deg)
Perspective Not needed for its 2D rotation Can enhance the 3D appearance

For example, these declarations produce equivalent rotations:

transform: rotate(45deg);
transform: rotate3d(0, 0, 1, 45deg);

Both rotate around the Z axis.

Use rotate() for ordinary two-dimensional rotation and rotate3d() when a custom three-dimensional axis is required.

Example

This example compares rotations around the X, Y, and combined X/Y axes.

HTML:

<div class="rotate3d-demo">
  <div class="rotate3d-demo-stage">
    <div class="rotate3d-demo-box rotate3d-demo-x">X Axis</div>
  </div>
  <div class="rotate3d-demo-stage">
    <div class="rotate3d-demo-box rotate3d-demo-y">Y Axis</div>
  </div>
  <div class="rotate3d-demo-stage">
    <div class="rotate3d-demo-box rotate3d-demo-xy">X + Y</div>
  </div>
</div>

CSS:

.rotate3d-demo {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 20px;
  padding: 25px 15px;
  background-color: #f1f3f5;
}
.rotate3d-demo-stage {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 130px;
  height: 140px;
  perspective: 500px;
  border: 1px dashed #999999;
}
.rotate3d-demo-box {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 95px;
  height: 95px;
  background-color: #0066cc;
  color: #ffffff;
  font-weight: bold;
  text-align: center;
  backface-visibility: visible;
}
.rotate3d-demo-x {
  transform: rotate3d(1, 0, 0, 50deg);
}
.rotate3d-demo-y {
  transform: rotate3d(0, 1, 0, 50deg);
}
.rotate3d-demo-xy {
  transform: rotate3d(1, 1, 0, 50deg);
}
Browser Result
X Axis
Y Axis
X + Y

The first box tilts around the horizontal axis, the second rotates around the vertical axis, and the third rotates around a diagonal axis combining both directions.

Each dashed container provides perspective, making the differences between the rotations easier to see.

Perspective Example

This example compares the same three-dimensional rotation with and without perspective.

HTML:

<div class="rotate3d-perspective-demo">
  <div class="rotate3d-perspective-stage rotate3d-perspective-flat">
    <div class="rotate3d-perspective-box">No Perspective</div>
  </div>
  <div class="rotate3d-perspective-stage rotate3d-perspective-depth">
    <div class="rotate3d-perspective-box">Perspective</div>
  </div>
</div>

CSS:

.rotate3d-perspective-demo {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 25px;
  padding: 25px 15px;
  background-color: #f1f3f5;
}
.rotate3d-perspective-stage {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 180px;
  height: 160px;
  border: 1px dashed #999999;
}
.rotate3d-perspective-box {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 110px;
  height: 100px;
  padding: 5px;
  background-color: #008577;
  color: #ffffff;
  font-weight: bold;
  text-align: center;
  transform: rotate3d(1, 1, 0, 55deg);
}
.rotate3d-perspective-flat {
  perspective: none;
}
.rotate3d-perspective-depth {
  perspective: 350px;
}
Browser Result
No Perspective
Perspective

Both boxes use the same rotation axis and angle.

The first uses an orthographic appearance without perspective. The second uses a perspective distance of 350px, making the nearer and farther portions appear different in size.

Transitions and Animations

The rotate3d() function can be used with CSS transitions and keyframe animations.

For example, a hover transition:

.rotate3d-hover {
  transition: transform 0.4s ease;
}
.rotate3d-hover:hover {
  transform: rotate3d(1, 1, 0, 35deg);
}

A continuous three-dimensional rotation can be created with keyframes:

@keyframes rotate3d-spin {
  from {
    transform: rotate3d(1, 1, 0, 0deg);
  }
  to {
    transform: rotate3d(1, 1, 0, 360deg);
  }
}
.rotate3d-spinner {
  animation: rotate3d-spin 3s linear infinite;
}

Both keyframes use the same rotation axis, producing a complete revolution around that axis.

For accessibility, disable nonessential animations when reduced motion is preferred:

@media (prefers-reduced-motion: reduce) {
  .rotate3d-spinner {
    animation: none;
  }
}

Three-dimensional rotation can also be combined with perspective and backface-visibility to create card-flipping effects.

Common Uses

The rotate3d() function is useful for three-dimensional visual effects and interactive interfaces.

Use Description
3D cardsTilt or rotate cards around custom axes.
Interactive panelsCreate depth effects on hover or focus.
CSS illustrationsOrient shapes in three-dimensional space.
Animated elementsCreate rotations around diagonal axes.
Product displaysSimulate rotating panels or objects.
Decorative effectsAdd perspective and depth to interface components.

For example:

.tilted-card {
  transform: perspective(700px) rotate3d(1, 1, 0, 15deg);
}
.rotated-panel {
  transform: rotate3d(0, 1, 0, 45deg);
}
.decorative-shape {
  transform: rotate3d(1, 1, 1, 30deg);
}

These examples demonstrate combined-axis rotation, rotation around the Y axis, and rotation around all three axes.

Limitations

The rotate3d() function has several important rules and considerations.

  • It requires three unitless axis numbers and one angle.
  • The axis vector cannot contain three zero values.
  • The axis vector is normalized before the rotation is applied.
  • The rotation angle requires a valid CSS angle unit.
  • Perspective is not automatically added by the function.
  • It does not change the element's original document layout space.
  • Transformed elements can overlap nearby content or extend beyond their containers.
  • The order of combined transform functions affects the final result.
  • Three-dimensional rotations can make text difficult to read when viewed at steep angles.
  • Nonessential animations should respect reduced-motion preferences.

For example, this is valid:

transform: rotate3d(1, 1, 0, 45deg);

The following is also valid, but a zero-length axis produces no rotation:

transform: rotate3d(0, 0, 0, 45deg);

The following is invalid because the rotation angle has no unit:

transform: rotate3d(1, 0, 0, 45);

The following is invalid because the function requires four arguments:

transform: rotate3d(1, 0, 45deg);

Use a nonzero axis vector and a valid angle to create a visible rotation.

Browser Support

The CSS rotate3d() function is Baseline Widely available and is supported by modern versions of Chrome, Edge, Firefox, Safari, and other major browsers.

It does not require vendor prefixes in modern browsers.

For example:

.box {
  transform: rotate3d(1, 1, 0, 45deg);
}

For older browsers that do not support three-dimensional transforms, a two-dimensional fallback can be provided:

.box {
  transform: rotate(15deg);
  transform: rotate3d(1, 1, 0, 45deg);
}

Browsers that support the 3D function use the second declaration. Browsers that do not recognize it can retain the earlier 2D rotation.

For current compatibility information, visit Can I Use? and search for CSS 3D transforms.

Specifications

The rotate3d() function is defined in the CSS Transforms Module Level 2 .

The specification defines three-dimensional transformations, rotation axes, perspective, and related transform behavior.

Related CSS functions include rotate(), rotateX(), rotateY(), rotateZ(), translate3d(), and scale3d().