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 |
|---|---|---|
deg | Degrees | 360deg |
rad | Radians | Approximately 6.283185rad |
grad | Gradians | 400grad |
turn | Revolutions | 1turn |
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);
}
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;
}
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 cards | Tilt or rotate cards around custom axes. |
| Interactive panels | Create depth effects on hover or focus. |
| CSS illustrations | Orient shapes in three-dimensional space. |
| Animated elements | Create rotations around diagonal axes. |
| Product displays | Simulate rotating panels or objects. |
| Decorative effects | Add 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().
