CSS matrix3d() Function

The CSS matrix3d() function defines a three-dimensional transformation using 16 numeric values arranged as a 4 × 4 transformation matrix.

It is used with the transform property to combine translation, scaling, rotation, skewing, and perspective into a single transformation. The function provides precise control over 3D effects, although individual transform functions are usually easier to read and maintain.

Syntax

matrix3d(
  m11, m12, m13, m14,
  m21, m22, m23, m24,
  m31, m32, m33, m34,
  m41, m42, m43, m44
)

The function requires exactly 16 comma-separated numbers.

For example:

.box {
  transform: matrix3d(
    1, 0, 0, 0,
    0, 1, 0, 0,
    0, 0, 1, 0,
    50, 20, 30, 1
  );
}

This moves the element 50 pixels to the right, 20 pixels down, and 30 pixels along the positive z-axis.

The function returns a CSS <transform-function> value.

All arguments are unitless numbers. Translation values are interpreted as CSS pixel offsets.

Unlike translate3d(), translation arguments in matrix3d() cannot directly use lengths such as em or percentages.

Parameters

The 16 arguments define the entries of a 4 × 4 transformation matrix.

Parameters Description
m11, m12, m13Define how the original x-coordinate contributes to the transformed x, y, and z coordinates.
m21, m22, m23Define how the original y-coordinate contributes to the transformed x, y, and z coordinates.
m31, m32, m33Define how the original z-coordinate contributes to the transformed x, y, and z coordinates.
m14, m24, m34Control how the original coordinates contribute to the homogeneous coordinate used for perspective.
m41, m42, m43Specify translation along the x, y, and z axes.
m44Controls the constant contribution to the homogeneous coordinate.

The first 12 arguments determine how coordinates are transformed, including the values used for perspective calculations.

The final four arguments include translation and the homogeneous coordinate component.

The values work together. Changing one coefficient can affect the apparent size, position, orientation, or perspective of the element.

How It Works

A 3D transformation matrix calculates new coordinates for points in three-dimensional space.

CSS uses the following mathematical matrix representation:

| m11  m21  m31  m41 |
| m12  m22  m32  m42 |
| m13  m23  m33  m43 |
| m14  m24  m34  m44 |

The arguments are listed in column-major order, meaning each group of four arguments represents one column.

For a point with coordinates (x, y, z), the transformation calculates:

x' = m11*x + m21*y + m31*z + m41
y' = m12*x + m22*y + m32*z + m42
z' = m13*x + m23*y + m33*z + m43
w' = m14*x + m24*y + m34*z + m44

When perspective is involved, the homogeneous coordinate w' affects the final projected position.

For example:

matrix3d(
  1, 0, 0, 0,
  0, 1, 0, 0,
  0, 0, 1, 0,
  40, 20, 0, 1
)

This preserves the element's size and orientation while translating it 40 pixels right and 20 pixels down.

The element's final visual position also depends on properties such as transform-origin and any perspective applied by its ancestors.

Identity Matrix

The identity matrix produces no visible transformation.

Its values are:

matrix3d(
  1, 0, 0, 0,
  0, 1, 0, 0,
  0, 0, 1, 0,
  0, 0, 0, 1
)

For example:

.box {
  transform: matrix3d(
    1, 0, 0, 0,
    0, 1, 0, 0,
    0, 0, 1, 0,
    0, 0, 0, 1
  );
}

The element retains its original position, size, and orientation.

This matrix is useful as a starting point when learning how the individual coefficients affect 3D transformations.

Translation

Translation moves an element along the x, y, or z axis.

For example:

.box {
  transform: matrix3d(
    1, 0, 0, 0,
    0, 1, 0, 0,
    0, 0, 1, 0,
    60, 30, 40, 1
  );
}

This moves the element 60 pixels right, 30 pixels down, and 40 pixels along the positive z-axis.

Equivalent CSS:

.box {
  transform: translate3d(60px, 30px, 40px);
}

Positive z-axis translation moves an element toward the viewer in the standard CSS 3D coordinate system.

Without perspective, moving an element along the z-axis may not produce an obvious visual change.

With perspective, moving toward the viewer generally makes the element appear larger.

Scaling

Scaling changes an element's size along the x, y, and z axes.

A scaling matrix uses the scale factors along its main diagonal:

matrix3d(
  scaleX, 0, 0, 0,
  0, scaleY, 0, 0,
  0, 0, scaleZ, 0,
  0, 0, 0, 1
)

For example:

.box {
  transform: matrix3d(
    1.5, 0, 0, 0,
    0, 1.5, 0, 0,
    0, 0, 1, 0,
    0, 0, 0, 1
  );
}

This scales the element to 150% of its original width and height.

Equivalent CSS:

.box {
  transform: scale3d(1.5, 1.5, 1);
}

Different scale factors can be applied to each axis:

transform: matrix3d(
  2, 0, 0, 0,
  0, 0.5, 0, 0,
  0, 0, 1.5, 0,
  0, 0, 0, 1
);

This doubles the x-axis scale, reduces the y-axis scale to 50%, and scales z-coordinates by 150%.

Scaling along the z-axis is most noticeable when the transformed element or its descendants have three-dimensional depth.

Rotation

A 3D matrix can represent rotation around the x, y, or z axis.

For example, a 90-degree rotation around the z-axis uses:

.box {
  transform: matrix3d(
    0, 1, 0, 0,
    -1, 0, 0, 0,
    0, 0, 1, 0,
    0, 0, 0, 1
  );
}

Equivalent CSS:

.box {
  transform: rotateZ(90deg);
}

A 45-degree rotation around the y-axis can be approximated with:

.box {
  transform: matrix3d(
    0.7071, 0, -0.7071, 0,
    0, 1, 0, 0,
    0.7071, 0, 0.7071, 0,
    0, 0, 0, 1
  );
}

Equivalent CSS:

.box {
  transform: rotateY(45deg);
}

Rotations around the x and y axes are easier to see when perspective is applied.

For most CSS layouts, rotateX(), rotateY(), and rotateZ() are simpler than manually calculating matrix coefficients.

Perspective

Perspective creates the appearance of depth by making objects farther from the viewer appear smaller.

A perspective transformation can be represented within a 3D matrix.

For example:

.box {
  transform: matrix3d(
    1, 0, 0, 0,
    0, 1, 0, 0,
    0, 0, 1, -0.002,
    0, 0, 0, 1
  );
}

This represents a perspective distance of 500 pixels because -1 / 500 equals -0.002.

Equivalent transform function:

.box {
  transform: perspective(500px);
}

A perspective transformation is most visible when combined with rotation or translation along the z-axis.

For example:

.box {
  transform: perspective(500px) rotateY(35deg);
}

Alternatively, the perspective property can be applied to a parent element to establish perspective for its transformed children.

The perspective property and the perspective() transform function are related but differ in how perspective is established and applied.

Combined Transformations

A single matrix3d() function can represent the result of multiple 3D transformations.

For example:

.box {
  transform: matrix3d(
    1.2, 0, 0, 0,
    0, 1.2, 0, 0,
    0, 0, 1, 0,
    40, 20, 30, 1
  );
}

This scales the element to 120% along the x and y axes and translates it 40 pixels right, 20 pixels down, and 30 pixels along the z-axis.

Equivalent CSS:

.box {
  transform: translate3d(40px, 20px, 30px) scale3d(1.2, 1.2, 1);
}

Transformation order is important. These declarations generally produce different results:

transform: translateZ(100px) rotateY(45deg);
transform: rotateY(45deg) translateZ(100px);

CSS transform functions are composed in their specified order, with operations applied to points from right to left.

A combined matrix must use the correct multiplication order to reproduce the intended transformation.

Transform Origin

The transform-origin property specifies the point around which an element is transformed.

For 3D transformations, it can include a z-axis offset.

For example:

.box {
  transform-origin: center center 50px;
  transform: rotateY(45deg);
}

This rotates the element around a point 50 pixels along the positive z-axis from its center.

The same origin can be used with a matrix:

.box {
  transform-origin: center center 50px;
  transform: matrix3d(
    0.7071, 0, -0.7071, 0,
    0, 1, 0, 0,
    0.7071, 0, 0.7071, 0,
    0, 0, 0, 1
  );
}

The transform origin affects the visible result of rotation and scaling.

For ordinary HTML elements, the default transform origin is the element's center, with a z-axis offset of zero.

Transform Style and Backface Visibility

Several CSS properties control how transformed elements behave in three-dimensional space.

The transform-style property determines whether an element's children are flattened into its plane or preserve their 3D positions.

For example:

.scene {
  perspective: 600px;
}
.object {
  transform-style: preserve-3d;
}
.object-face {
  transform: translateZ(40px);
}

The preserve-3d value allows eligible descendants to participate in the same 3D rendering context.

The backface-visibility property controls whether the reverse side of a transformed element is visible:

.card {
  backface-visibility: hidden;
}

This is useful for card-flipping effects and other 3D interfaces.

Some properties, including certain clipping and opacity effects, can cause descendants to be flattened even when preserve-3d is specified.

These properties work with matrix3d() but are not arguments of the function itself.

matrix3d() vs. matrix()

The matrix3d() function extends the two-dimensional matrix model to three-dimensional transformations.

Feature matrix() matrix3d()
Dimensions2D3D
Arguments616
Matrix size3 × 34 × 4
X and Y translationYesYes
Z-axis translationNoYes
3D rotationNoYes
PerspectiveNoYes

For example, a 2D translation can be written as:

transform: matrix(1, 0, 0, 1, 50, 20);

The equivalent 3D matrix is:

transform: matrix3d(
  1, 0, 0, 0,
  0, 1, 0, 0,
  0, 0, 1, 0,
  50, 20, 0, 1
);

Use matrix() for 2D transformations and matrix3d() when 3D coordinates or perspective are required.

Example

This example compares an unchanged element with an element transformed using matrix3d().

HTML:

<div class="matrix3d-demo">
  <div class="matrix3d-demo-item">
    <span>Original</span>
    <div class="matrix3d-demo-stage">
      <div class="matrix3d-demo-box">Box</div>
    </div>
  </div>
  <div class="matrix3d-demo-item">
    <span>Translated and Scaled</span>
    <div class="matrix3d-demo-stage">
      <div class="matrix3d-demo-box matrix3d-demo-transformed">Box</div>
    </div>
  </div>
</div>

CSS:

.matrix3d-demo {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 15px;
}
.matrix3d-demo-item {
  min-width: 0;
}
.matrix3d-demo-item span {
  display: block;
  margin-bottom: 8px;
  font-size: 12px;
}
.matrix3d-demo-stage {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 150px;
  background-color: #f1f3f5;
  border: 1px solid #dddddd;
  overflow: hidden;
}
.matrix3d-demo-box {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 75px;
  height: 55px;
  background-color: #0066cc;

  color: #ffffff;
  font-size: 13px;
}
.matrix3d-demo-transformed {
  transform: matrix3d(
    1.2, 0, 0, 0,
    0, 1.2, 0, 0,
    0, 0, 1, 0,
    20, 10, 0, 1
  );
}
Browser Result
Original
Box
Translated and Scaled
Box

The transformed box is scaled to 120% and moved 20 pixels right and 10 pixels down.

Although the transformation is expressed using a 3D matrix, this example does not introduce visible depth because no perspective or z-axis rotation is applied.

Perspective Example

This example uses a 3D rotation matrix with a parent perspective to create a visible depth effect.

HTML:

<div class="matrix3d-perspective-demo">
  <div class="matrix3d-perspective-box">3D Rotation</div>
</div>

CSS:

.matrix3d-perspective-demo {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 200px;
  background-color: #f1f3f5;
  perspective: 500px;
}
.matrix3d-perspective-box {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 140px;
  height: 90px;
  background-color: #0066cc;
  color: #ffffff;
  border: 2px solid #004499;
  border-radius: 4px;
  font-size: 16px;
  transform: matrix3d(
    0.7071, 0, -0.7071, 0,
    0, 1, 0, 0,
    0.7071, 0, 0.7071, 0,
    0, 0, 0, 1
  );
}
Browser Result
3D Rotation

The matrix rotates the element approximately 45 degrees around the y-axis.

The parent's perspective property makes the nearer side appear larger and the farther side appear smaller.

This creates a visible 3D effect without using an image.

Common Uses

The matrix3d() function is useful when a complete three-dimensional transformation must be expressed as one matrix.

Use Description
3D interfacesCreate transformed panels, cards, and interface elements.
Combined transformationsRepresent several 3D operations in one function.
Perspective effectsControl projected depth using matrix coefficients.
Generated transformationsApply matrices calculated by scripts or design tools.
Animation systemsRepresent complex transformation states.
3D positioningMove and orient elements along three axes.

For example:

.panel {
  transform: matrix3d(
    0.866, 0, -0.5, 0,
    0, 1, 0, 0,
    0.5, 0, 0.866, 0,
    20, 0, 30, 1
  );
}

This represents an approximate 30-degree rotation around the y-axis combined with translation.

For simple transformations, individual functions such as translate3d(), rotateY(), and scale3d() are usually easier to maintain.

Limitations

The matrix3d() function has several important rules and limitations.

  • Exactly 16 comma-separated arguments are required.
  • Every argument must resolve to a number without CSS units.
  • Translation arguments represent CSS pixel offsets.
  • Matrix coefficients are difficult to calculate and maintain manually.
  • The order of combined transformations affects the result.
  • Perspective may be required to make some 3D effects visually apparent.
  • Transforms change visual rendering without changing normal document flow.
  • Some matrices can produce degenerate or non-renderable transformations.
  • Transforms may create stacking contexts and affect positioned descendants.
  • Properties such as transform-style and backface-visibility can affect 3D rendering.

For example, this is valid:

transform: matrix3d(
  1, 0, 0, 0,
  0, 1, 0, 0,
  0, 0, 1, 0,
  50, 20, 0, 1
);

The following is invalid because it supplies only six arguments:

transform: matrix3d(1, 0, 0, 1, 50, 20);

The following is invalid because the translation values contain CSS length units:

transform: matrix3d(
  1, 0, 0, 0,
  0, 1, 0, 0,
  0, 0, 1, 0,
  50px, 20px, 0, 1
);

Use translate3d() when translation values require CSS lengths rather than numeric matrix arguments.

Browser Support

The CSS matrix3d() function is Baseline Widely available and has been supported across major browser engines for many years.

Modern versions of Chrome, Edge, Firefox, Safari, and other major browsers support 3D transformation matrices.

For example:

.box {
  transform: matrix3d(
    1, 0, 0, 0,
    0, 1, 0, 0,
    0, 0, 1, 0,
    50, 20, 0, 1
  );
}

Very old browsers may require vendor-prefixed transform declarations, but prefixes are unnecessary in modern browsers.

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

Specifications

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

The specification defines 3D transformation matrices, perspective, transform composition, and related three-dimensional rendering behavior.

Related CSS functions include matrix(), translate3d(), scale3d(), rotate3d(), and perspective().