matrix() and matrix3d() Transforms
matrix() and matrix3d() are low-level CSS transform functions that accept a matrix of numeric values. They can represent any 2D or 3D transformation (translate, rotate, scale, skew). Most developers use specific functions like translate() or rotate(), but matrix is useful for advanced animations, dynamic calculations, and understanding transforms mathematically.
The matrix() function
CSS
/* matrix(a, b, c, d, e, f) for 2D transforms */
/* a, b, c, d = rotation/scale/skew (4x4 part of matrix) */
/* e, f = translation (tx, ty) */
/* Example: identity matrix (no change) */
.identity {
transform: matrix(1, 0, 0, 1, 0, 0);
/* No transformation applied */
}
/* Translate 100px right, 50px down */
.translate {
transform: matrix(1, 0, 0, 1, 100, 50);
/* Equivalent to translateX(100px) translateY(50px) */
}
/* Scale 2x */
.scale {
transform: matrix(2, 0, 0, 2, 0, 0);
/* Equivalent to scale(2) */
}
/* Rotate 45 degrees */
.rotate-matrix {
transform: matrix(0.707, 0.707, -0.707, 0.707, 0, 0);
/* cos(45°), sin(45°), -sin(45°), cos(45°), 0, 0 */
/* Equivalent to rotate(45deg) */
}
/* Skew effect */
.skew-matrix {
transform: matrix(1, 0, 0.5, 1, 0, 0);
/* Creates skew transformation */
}
/* Combined: translate + scale */
.combined {
transform: matrix(2, 0, 0, 2, 50, 50);
/* Scales 2x and translates 50px each direction */
}Matrix formula and values
Parameter | Purpose | Default | Range |
|---|---|---|---|
a | Horizontal scale + rotation | 1 | Any value |
b | Vertical skew + rotation | 0 | Any value |
c | Horizontal skew + rotation | 0 | Any value |
d | Vertical scale + rotation | 1 | Any value |
e | Horizontal translation (tx) | 0 | Any value |
f | Vertical translation (ty) | 0 | Any value |
CSS
/* Understanding the matrix formula */
/* For a point (x, y), matrix transformation is: */
/* x' = a*x + c*y + e */
/* y' = b*x + d*y + f */
/* Translation only (move 100px, 50px) */
.translate-only {
transform: matrix(1, 0, 0, 1, 100, 50);
}
/* Scale only (double size) */
.scale-only {
transform: matrix(2, 0, 0, 2, 0, 0);
}
/* Rotation by angle θ (convert degrees to radians) */
/* cos(θ), sin(θ), -sin(θ), cos(θ), 0, 0 */
.rotate-30deg {
/* Math.cos(30deg) ≈ 0.866, Math.sin(30deg) = 0.5 */
transform: matrix(0.866, 0.5, -0.5, 0.866, 0, 0);
}
/* Skew X by 20 degrees */
.skew-x-20 {
/* tan(20deg) ≈ 0.364 */
transform: matrix(1, 0, 0.364, 1, 0, 0);
}
/* Complex: rotate, scale, translate */
.complex-matrix {
/* This is harder to calculate manually */
/* Better to use individual transform functions */
transform: rotate(45deg) scale(1.5) translate(20px, 30px);
}matrix3d() for 3D transforms
CSS
/* matrix3d(a1, b1, c1, d1, a2, b2, c2, d2, a3, b3, c3, d3, a4, b4, c4, d4) */
/* 16-value 4x4 matrix for 3D transformations */
/* Identity 3D matrix (no change) */
.identity-3d {
transform: matrix3d(
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1
);
}
/* Translate in 3D (100px X, 50px Y, 20px Z) */
.translate-3d {
transform: matrix3d(
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
100, 50, 20, 1
);
/* Equivalent to translate3d(100px, 50px, 20px) */
}
/* Scale in 3D (2x on all axes) */
.scale-3d {
transform: matrix3d(
2, 0, 0, 0,
0, 2, 0, 0,
0, 0, 2, 0,
0, 0, 0, 1
);
/* Equivalent to scale3d(2, 2, 2) */
}
/* Rotate around Z axis (like 2D rotate) */
.rotate-z-3d {
transform: matrix3d(
0.866, 0.5, 0, 0,
-0.5, 0.866, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1
);
/* 30 degree rotation around Z axis */
}
/* Rotate around X axis (pitch) */
.rotate-x-3d {
transform: matrix3d(
1, 0, 0, 0,
0, 0.866, 0.5, 0,
0, -0.5, 0.866, 0,
0, 0, 0, 1
);
/* 30 degree rotation around X axis */
}When to use matrix
CSS
/* Most of the time: use specific functions */
/* Good: readable and maintainable */
.good {
transform: translateX(50px) rotate(45deg) scale(1.5);
}
/* Avoid: matrix is harder to read */
.bad {
/* This matrix = translateX(50px) rotate(45deg) scale(1.5) */
transform: matrix(1.06, 1.06, -1.06, 1.06, 50, 0);
/* Hard to understand what this does */
}
/* Use matrix when: */
/* 1. Dynamically calculating transforms with JavaScript */
/* Example: calculating rotation from mouse position */
.javascript-transform {
/* In JS: calculated at runtime, not in CSS */
transform: matrix(cos, sin, -sin, cos, tx, ty);
}
/* 2. Combining multiple transforms for animation */
@keyframes complex-anim {
0% {
transform: matrix(1, 0, 0, 1, 0, 0);
}
50% {
transform: matrix(1.5, 0.2, 0.1, 1.3, 30, 20);
}
100% {
transform: matrix(1, 0, 0, 1, 60, 0);
}
}
/* 3. Converting from other systems */
/* (Canvas, SVG, graphics libraries) */
/* Better approach: use CSS custom properties */
:root {
--tx: 50px;
--ty: 50px;
--angle: 45deg;
--scale: 1.5;
}
.element {
transform: translateX(var(--tx))
translateY(var(--ty))
rotate(var(--angle))
scale(var(--scale));
/* Clear intent, easy to modify */
}Browser compatibility and browser tools
CSS
/* Browser DevTools help with matrix debugging */
/* In Chrome/Firefox DevTools: */
/* 1. Inspect element */
/* 2. Computed tab shows expanded transforms */
/* 3. Hover over transform value to see visual */
/* Use autoprefixer for older browsers */
.prefixed {
-webkit-transform: matrix(1.5, 0, 0, 1.5, 50, 50);
-moz-transform: matrix(1.5, 0, 0, 1.5, 50, 50);
-ms-transform: matrix(1.5, 0, 0, 1.5, 50, 50);
-o-transform: matrix(1.5, 0, 0, 1.5, 50, 50);
transform: matrix(1.5, 0, 0, 1.5, 50, 50);
}
/* matrix3d support is good in modern browsers */
.matrix3d-element {
transform: matrix3d(
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
50, 50, 20, 1
);
/* Supported in all modern browsers */
}Converting between formats
CSS
/* These are equivalent: */
/* Version 1: Readable individual transforms */
.method-1 {
transform: translateX(100px) translateY(50px) rotate(45deg) scale(1.5);
}
/* Version 2: Combined matrix (harder to read) */
.method-2 {
/* Calculated from: translate(100px, 50px) rotate(45deg) scale(1.5) */
/* Real matrix values depend on exact math */
transform: matrix(1.06, 1.06, -1.06, 1.06, 50, 50);
}
/* Tips for conversion: */
/* - Use browser DevTools to inspect computed values */
/* - Use mathematical tools to calculate matrix values */
/* - When in doubt, stick with individual transforms */
/* Complex animation example */
@keyframes smooth-motion {
0% {
transform: translateX(0) rotate(0deg) scale(1);
}
50% {
transform: translateX(100px) rotate(180deg) scale(1.2);
}
100% {
transform: translateX(200px) rotate(360deg) scale(1);
}
}
.animated-element {
animation: smooth-motion 3s ease-in-out infinite;
/* Much clearer than trying to hand-calculate matrix values */
}Warning
`matrix()` and `matrix3d()` are powerful but complex. Most CSS developers never need to use them directly—use specific functions like `translate()`, `rotate()`, `scale()`, and `skew()` instead. Only resort to matrix when: (1) dynamically calculating transforms in JavaScript, (2) converting from other graphics systems, or (3) working with pre-calculated animation values. Prefer clarity over brevity.
Note
`matrix()` combines 2D transformations into a single 6-value function: `matrix(a, b, c, d, e, f)`. `matrix3d()` extends this with 16 values for 3D. Both are powerful for mathematical transformations but harder to read than individual functions. Use `translate()`, `rotate()`, `scale()`, `skew()` for clarity. Reserve matrix for dynamic calculations or advanced use cases.
Next
Transform origin: [transform-origin](/css/transform-origin).