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%;}
<img src="https://cdn.pixabay.com/photo/2022/09/26/23/26/african-american-7481724_960_720.jpg" alt=""/>
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%;}
<img src="https://cdn.pixabay.com/photo/2022/09/26/23/26/african-american-7481724_960_720.jpg" alt=""/>
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:
| scX skX tX | ← x-axis| skY scY tY | ← y-axis| 0 0 1 | ← constants
Note the following:
scX
andskX
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
andscY
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.
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%;}
<img src="https://cdn.pixabay.com/photo/2022/09/26/23/26/african-american-7481724_960_720.jpg" alt=""/>
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%;}
<img src="https://cdn.pixabay.com/photo/2022/09/26/23/26/african-american-7481724_960_720.jpg" alt=""/>
Let’s also represent the matrix’s values as homogeneous coordinates on ℝℙ2:
| 2 0 0 | ← x-axis| 0 1 0 | ← y-axis| 0 0 1 | ← constants
Below is another example.
How to convert translateY()
to matrix()
function
img { transform-origin: 0 0; transform: translateY(250px); width: 80%;}
<img src="https://cdn.pixabay.com/photo/2022/09/26/23/26/african-american-7481724_960_720.jpg" alt=""/>
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%;}
<img src="https://cdn.pixabay.com/photo/2022/09/26/23/26/african-american-7481724_960_720.jpg" alt=""/>
Let’s also represent the matrix’s values as homogeneous coordinates on ℝℙ2:
| 1 0 0 | ← x-axis| 0 1 250 | ← y-axis| 0 0 1 | ← constants
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%;}
<img src="https://cdn.pixabay.com/photo/2022/09/26/23/26/african-american-7481724_960_720.jpg" alt=""/>
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:
| 1 0 100 | ← x-axis| 0 1 0 | ← y-axis| 0 0 1 | ← constants
Let’s also define scale(2)
’s homogeneous coordinates:
| 2 0 0 | ← x-axis| 0 2 0 | ← y-axis| 0 0 1 | ← constants
It’s now time to multiply the two homogeneous coordinates by using the following syntax:
| a d g | | j m p | | aj + dk + gl am + dn + go ap +dq + gr || b e h | x | k n q | = | bj + ek + hl bm + en + ho bp + eq + hr || c f i | | l o r | | cj + fk + il cm + fn + io cp + fq + ir |
Let’s implement the above syntax like so:
| 1 0 100 | | 2 0 0 | | 2 + 0 + 0 0 + 0 + 0 0 + 0 + 100 || 0 1 0 | x | 0 2 0 | = | 0 + 0 + 0 0 + 2 + 0 0 + 0 + 0 || 0 0 1 | | 0 0 1 | | 0 + 0 + 0 0 + 0 + 0 0 + 0 + 1 |
The next step is to resolve the addition. So, let’s do that now.
| 1 0 100 | | 2 0 0 | | 2 0 100 || 0 1 0 | x | 0 2 0 | = | 0 2 0 || 0 0 1 | | 0 0 1 | | 0 0 1 |
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:
| 2 0 100 | ← x-axis| 0 2 0 | ← y-axis| 0 0 1 | ← constants
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%;}
<img src="https://cdn.pixabay.com/photo/2022/09/26/23/26/african-american-7481724_960_720.jpg" alt=""/>
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%;}
<img src="https://cdn.pixabay.com/photo/2022/09/26/23/26/african-american-7481724_960_720.jpg" alt=""/>
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:
| 2 0 0 | ← x-axis| 0 2 0 | ← y-axis| 0 0 1 | ← constants
Let’s also define translateX(100px)
’s homogeneous coordinates:
| 1 0 100 | ← x-axis| 0 1 0 | ← y-axis| 0 0 1 | ← constants
It’s now time to multiply the two homogeneous coordinates by using the following syntax:
| a d g | | j m p | | aj + dk + gl am + dn + go ap +dq + gr || b e h | x | k n q | = | bj + ek + hl bm + en + ho bp + eq + hr || c f i | | l o r | | cj + fk + il cm + fn + io cp + fq + ir |
Let’s implement the above syntax like so:
| 2 0 0 | | 1 0 100 | | 2 + 0 + 0 0 + 0 + 0 200 + 0 + 0 || 0 2 0 | x | 0 1 0 | = | 0 + 0 + 0 0 + 2 + 0 0 + 0 + 0 || 0 0 1 | | 0 0 1 | | 0 + 0 + 0 0 + 0 + 0 0 + 0 + 1 |
The next step is to resolve the addition. So, let’s do that now.
| 2 0 0 | | 1 0 100 | | 2 0 200 || 0 2 0 | x | 0 1 0 | = | 0 2 0 || 0 0 1 | | 0 0 1 | | 0 0 1 |
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:
| 2 0 200 | ← x-axis| 0 2 0 | ← y-axis| 0 0 1 | ← constants
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%;}
<img src="https://cdn.pixabay.com/photo/2022/09/26/23/26/african-american-7481724_960_720.jpg" alt=""/>
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);}
<div class="red"></div><div class="green"></div><div class="blue"></div>
The only difference between the green and the blue div
s 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 div
s’ 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:
- Use the
id
attribute to get the image element. - Use the
window.getComputedStyle()
method to get the image’stransform
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);
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:
- Go to The Matrix Resolutions website: https://meyerweb.com/eric/tools/matrix/.
- Paste your transform functions (
scale(2) translateX(100px)
) into the first text field. - Click “The Red Pill” button to generate the transform functions’ matrix equivalence.
Click the red pill button to convert CSS transform functions to a matrix() function