Skip to main content

CSS matrix() Function – How to Create a 2D Transformation Matrix

The CSS matrix() function is a shorthand for the following 2D transform functions:

In other words, instead of writing:

img {
transform-origin: 0 0;
transform: translateX(100px) translateY(250px) scaleX(2) scaleY(0.9) skewX(
10deg
) skewY(35deg);
width: 80%;
}

Try Editing It

You can alternatively use the matrix() function to shorten your code like so:

img {
transform-origin: 0 0;
transform: matrix(2.24693, 0.630187, 0.352654, 0.9, 100, 250);
width: 80%;
}

Try Editing It

The CSS matrix() Function's Syntax

The matrix() function accepts six values. Here's the syntax:

matrix(scaleX(), skewY(), skewX(), scaleY(), translateX(), translateY())

You can represent the CSS matrix's values as homogeneous coordinates on ℝℙ2 like so:

(scXskXtXskYscYtY001)\begin{pmatrix} scX & skX & tX \\ skY & scY & tY \\ 0 & 0 & 1 \end{pmatrix}

Note the following:

  • scX and skX are numbers describing an element's scale and skew linear transformation on the x-axis.
  • tX is a number representing an element's translation on the x-axis.
  • skY and scY are numbers describing an element's skew and scale linear transformation on the y-axis.
  • tY is a number representing an element's translation on the y-axis.
  • 0, 0, 1 are constants.
  • We do not pass the constants as arguments to the matrix() function because the computer implies them automatically.
CodeSweetly ads

Master NPM Package Creation

Elevate your skills, boost your projects, and stand out in the coding world.
Learn more

Examples of the CSS matrix() Function

Below are some examples of the CSS matrix() function.

How to convert scaleX() to matrix() function

Consider the following transform property:

img {
transform-origin: 0 0;
transform: scaleX(2);
width: 80%;
}

Try Editing It

Here is the matrix() equivalent of the above scaleX() function:

img {
transform-origin: 0 0;
transform: matrix(2, 0, 0, 1, 0, 0); /* scX, skY, skX, scY, tX, tY */
width: 80%;
}

Try Editing It

Let's also represent the matrix's values as homogeneous coordinates on ℝℙ2:

(200010001)\begin{pmatrix} 2 & 0 & 0 \\ 0 & 1 & 0 \\ 0 & 0 & 1 \end{pmatrix}

Below is another example.

How to convert translateY() to matrix() function

img {
transform-origin: 0 0;
transform: translateY(250px);
width: 80%;
}

Try Editing It

Here is the matrix() equivalent of the above translateY() function:

img {
transform-origin: 0 0;
transform: matrix(1, 0, 0, 1, 0, 250); /* scX, skY, skX, scY, tX, tY */
width: 80%;
}

Try Editing It

Let's also represent the matrix's values as homogeneous coordinates on ℝℙ2:

(10001250001)\begin{pmatrix} 1 & 0 & 0 \\ 0 & 1 & 250 \\ 0 & 0 & 1 \end{pmatrix}

Below is a third example.

How to convert translateX() and scale() to matrix() function

img {
transform-origin: 0 0;
transform: translateX(100px) scale(2);
width: 80%;
}

Try Editing It

Here is the syntax for converting the above transform property's value to matrix():

matrix = (translateX's homogeneous coordinates) x (scale's homogeneous coordinates)

Let's begin the conversion by defining translateX(100px)'s homogeneous coordinates:

(10100010001)\begin{pmatrix} 1 & 0 & 100 \\ 0 & 1 & 0 \\ 0 & 0 & 1 \end{pmatrix}

Let's also define scale(2)'s homogeneous coordinates:

(200020001)\begin{pmatrix} 2 & 0 & 0 \\ 0 & 2 & 0 \\ 0 & 0 & 1 \end{pmatrix}

It's now time to multiply the two homogeneous coordinates by using the following syntax:

(adgbehcfi)×(jmpknqlor)=\begin{pmatrix} a & d & g \\ b & e & h \\ c & f & i \end{pmatrix} × \begin{pmatrix} j & m & p \\ k & n & q \\ l & o & r \end{pmatrix} = (aj+dk+glam+dn+goap+dq+grbj+ek+hlbm+en+hobp+eq+hrcj+fk+ilcm+fn+iocp+fq+ir)\begin{pmatrix} aj & + & dk & + & gl && am & + & dn & + & go && ap & + & dq & + & gr \\ bj & + & ek & + & hl && bm & + & en & + & ho && bp & + & eq & + & hr \\ cj & + & fk & + & il && cm & + & fn & + & io && cp & + & fq & + & ir \end{pmatrix}

Let's implement the above syntax like so:

(10100010001)×(200020001)=\begin{pmatrix} 1 & 0 & 100 \\ 0 & 1 & 0 \\ 0 & 0 & 1 \end{pmatrix} × \begin{pmatrix} 2 & 0 & 0 \\ 0 & 2 & 0 \\ 0 & 0 & 1 \end{pmatrix} = (2+0+00+0+00+0+1000+0+00+2+00+0+00+0+00+0+00+0+1)\begin{pmatrix} 2 & + & 0 & + & 0 && 0 & + & 0 & + & 0 && 0 & + & 0 & + & 100 \\ 0 & + & 0 & + & 0 && 0 & + & 2 & + & 0 && 0 & + & 0 & + & 0 \\ 0 & + & 0 & + & 0 && 0 & + & 0 & + & 0 && 0 & + & 0 & + & 1 \end{pmatrix}

The next step is to resolve the addition. So, let's do that now.

(10100010001)×(200020001)=(20100020001)\begin{pmatrix} 1 & 0 & 100 \\ 0 & 1 & 0 \\ 0 & 0 & 1 \end{pmatrix} × \begin{pmatrix} 2 & 0 & 0 \\ 0 & 2 & 0 \\ 0 & 0 & 1 \end{pmatrix} = \begin{pmatrix} 2 & 0 & 100 \\ 0 & 2 & 0 \\ 0 & 0 & 1 \end{pmatrix}

The addition's result above gives us the homogeneous coordinates of the transform: translateX(100px) scale(2) property.

In other words, the product of (translateX's homogeneous coordinates) and (scale's homogeneous coordinates) equal:

(20100020001)\begin{pmatrix} 2 & 0 & 100 \\ 0 & 2 & 0 \\ 0 & 0 & 1 \end{pmatrix}

Therefore, the matrix equivalence of transform: translateX(100px) scale(2) is transform: matrix(2, 0, 0, 2, 100, 0).

img {
transform-origin: 0 0;
transform: matrix(2, 0, 0, 2, 100, 0);
width: 80%;
}

Try Editing It

Please note that transform: translateX(100px) scale(2) and transform: scale(2) translateX(100px) return different matrixes. Let's see an example of the second arrangement below.

How to convert scale() and translateX() to matrix() function

Consider the following transform property:

img {
transform-origin: 0 0;
transform: scale(2) translateX(100px);
width: 80%;
}

Try Editing It

Here is the syntax for converting the above transform property's value to matrix():

matrix = (scale's homogeneous coordinates) x (translateX's homogeneous coordinates)

Let's begin the conversion by defining scale(2)'s homogeneous coordinates:

(200020001)\begin{pmatrix} 2 & 0 & 0 \\ 0 & 2 & 0 \\ 0 & 0 & 1 \end{pmatrix}

Let's also define translateX(100px)'s homogeneous coordinates:

(10100010001)\begin{pmatrix} 1 & 0 & 100 \\ 0 & 1 & 0 \\ 0 & 0 & 1 \end{pmatrix}

It's now time to multiply the two homogeneous coordinates by using the following syntax:

(adgbehcfi)×(jmpknqlor)=\begin{pmatrix} a & d & g \\ b & e & h \\ c & f & i \end{pmatrix} × \begin{pmatrix} j & m & p \\ k & n & q \\ l & o & r \end{pmatrix} = (aj+dk+glam+dn+goap+dq+grbj+ek+hlbm+en+hobp+eq+hrcj+fk+ilcm+fn+iocp+fq+ir)\begin{pmatrix} aj & + & dk & + & gl && am & + & dn & + & go && ap & + & dq & + & gr \\ bj & + & ek & + & hl && bm & + & en & + & ho && bp & + & eq & + & hr \\ cj & + & fk & + & il && cm & + & fn & + & io && cp & + & fq & + & ir \end{pmatrix}

Let's implement the above syntax like so:

(200020001)×(10100010001)=\begin{pmatrix} 2 & 0 & 0 \\ 0 & 2 & 0 \\ 0 & 0 & 1 \end{pmatrix} × \begin{pmatrix} 1 & 0 & 100 \\ 0 & 1 & 0 \\ 0 & 0 & 1 \end{pmatrix} = (2+0+00+0+0200+0+00+0+00+2+00+0+00+0+00+0+00+0+1)\begin{pmatrix} 2 & + & 0 & + & 0 && 0 & + & 0 & + & 0 && 200 & + & 0 & + & 0 \\ 0 & + & 0 & + & 0 && 0 & + & 2 & + & 0 && 0 & + & 0 & + & 0 \\ 0 & + & 0 & + & 0 && 0 & + & 0 & + & 0 && 0 & + & 0 & + & 1 \end{pmatrix}

The next step is to resolve the addition. So, let's do that now.

(200020001)×(10100010001)=(20200020001)\begin{pmatrix} 2 & 0 & 0 \\ 0 & 2 & 0 \\ 0 & 0 & 1 \end{pmatrix} × \begin{pmatrix} 1 & 0 & 100 \\ 0 & 1 & 0 \\ 0 & 0 & 1 \end{pmatrix} = \begin{pmatrix} 2 & 0 & 200 \\ 0 & 2 & 0 \\ 0 & 0 & 1 \end{pmatrix}

The addition's result above gives us the homogeneous coordinates of the transform: scale(2) translateX(100px) property.

In other words, the product of (scale's homogeneous coordinates) and (translateX's homogeneous coordinates) equal:

(20200020001)\begin{pmatrix} 2 & 0 & 200 \\ 0 & 2 & 0 \\ 0 & 0 & 1 \end{pmatrix}

Therefore, the matrix equivalence of transform: scale(2) translateX(100px) is transform: matrix(2, 0, 0, 2, 200, 0).

img {
transform-origin: 0 0;
transform: matrix(2, 0, 0, 2, 200, 0);
width: 80%;
}

Try Editing It

Notice that transform: scale(2) translateX(100px) equals transform: matrix(2, 0, 0, 2, 200, 0). And transform: translateX(100px) scale(2) is equivalent to transform: matrix(2, 0, 0, 2, 100, 0).

In other words, the order in which you write the transform functions matters. Let's discuss more on this below.

Why Does the CSS Transform Functions' Order Matter?

The order in which you write CSS transform functions matters because of the way browsers calculate the matrix's values.

For instance, consider the following snippet:

div {
position: absolute;
width: 100px;
height: 100px;
transform-origin: 0 0;
}

.red {
border: 3px solid red;
background-color: rgba(255, 0, 0, 0.5);
}

.green {
border: 3px solid green;
background-color: rgba(0, 128, 0, 0.5);
transform: translateX(100px) scale(2);
}

.blue {
border: 3px solid blue;
background-color: rgba(0, 0, 255, 0.5);
transform: scale(2) translateX(100px);
}

Try Editing It

The only difference between the green and the blue divs is the order in which we wrote their transform functions.

However, the computer translated the two containers using different values (100px for the green div and 200px for the blue one).

So, why did the transform functions' order affect the divs' translation values? Here's the reason:

  • Browsers multiply each transform function's homogeneous coordinates in order—from left to right.

In other words, the computer used the following syntax to compute the green div's matrix:

  • Green div's matrix = (translateX's homogeneous coordinates) x (scale's homogeneous coordinates)

And it used the following syntax to calculate the blue div's matrix:

  • Blue div's matrix = (scale's homogeneous coordinates) x (translateX's homogeneous coordinates)

Therefore, the position of the transform functions determined the matrix's arguments because browsers began the calculation in order from the leftmost function to the right.

Knowing how to convert transform functions to matrix() is beneficial. And having some conversion tools can come in handy. So, let's discuss some helpful tools you can use.

Tools for Converting Transform Functions to matrix()

The two tools you can use to do a quick conversion of transform functions to matrix() are:

  • JavaScript's window.getComputedStyle() method
  • Eric Meyer and Aaron Gustafson's matrix resolution tool

How to use window.getComputedStyle() to convert transform functions to matrix()

Suppose you want to convert the following transform functions to matrix:

img {
transform-origin: 0 0;
transform: scale(2) translateX(100px);
width: 80%;
}

You will add an id attribute to the image element:

<img
src="https://cdn.pixabay.com/photo/2022/09/26/23/26/african-american-7481724_960_720.jpg"
alt=""
id="image"
/>

Then, in JavaScript, you will:

  1. Use the id attribute to get the image element.
  2. Use the window.getComputedStyle() method to get the image's transform property's value.

Here's the code:

// Get the image element by its id name:
const image = document.getElementById("image");

// Get the image element's transform property's value:
const matrix = window.getComputedStyle(image).getPropertyValue("transform");

// Log the matrix variable's value to the console:
console.log(matrix);

Try Editing It

Browsers, by default, convert a CSS transform property's value to its matrix equivalent. So, the snippet above returned the image's computed value.

Let's now discuss the second conversion tool.

How to use the matrix resolutions tool to convert transform functions to matrix()

Suppose you want to convert the following transform functions to a matrix():

img {
transform-origin: 0 0;
transform: scale(2) translateX(100px);
width: 80%;
}

You will do the following:

  1. Go to The Matrix Resolutions website: https://meyerweb.com/eric/tools/matrix/.
  2. Paste your transform functions (scale(2) translateX(100px)) into the first text field.
  3. Click "The Red Pill" button to generate the transform functions' matrix equivalence.

The matrix resolutions tool&#39;s
screenshot

Click the red pill button to convert CSS transform functions to a matrix() function

tip

Use matrix3d() to create a 3D transformation matrix.

Overview

This article discussed what a CSS matrix() function is. We also used examples to see how it works.

Your support matters: Buy me a coffee to support CodeSweetly's mission of simplifying coding concepts.

Join CodeSweetly Newsletter