821

Using CSS, how can I apply more than one transform?

Example: In the following, only the translation is applied, not the rotation.

li:nth-child(2) {
    transform: rotate(15deg);
    transform: translate(-20px,0px);        
}
Temani Afif
  • 245,468
  • 26
  • 309
  • 415
Ben
  • 15,938
  • 19
  • 92
  • 138

9 Answers9

1356

You have to put them on one line like this:

li:nth-child(2) {
    transform: rotate(15deg) translate(-20px,0px);
}

When you have multiple transform directives, only the last one will be applied. It's like any other CSS rule.


Keep in mind multiple transform one line directives are applied from right to left.

This: transform: scale(1,1.5) rotate(90deg);
and: transform: rotate(90deg) scale(1,1.5);

will not produce the same result:

.orderOne, .orderTwo {
  font-family: sans-serif;
  font-size: 22px;
  color: #000;
  display: inline-block;
}

.orderOne {
  transform: scale(1, 1.5) rotate(90deg);
}

.orderTwo {
  transform: rotate(90deg) scale(1, 1.5);
}
<div class="orderOne">
  A
</div>

<div class="orderTwo">
  A
</div>
isherwood
  • 58,414
  • 16
  • 114
  • 157
lukad
  • 17,287
  • 3
  • 36
  • 53
  • 66
    I tried separating them by a "," like its done with multiple shadows, but that didn't work. Thank you. – Ben May 26 '12 at 12:14
  • 2
    is it possible to apply one tranformation before other...like skew before rotate. As for me no matter what i do, element is rotated first and then skewed which results in something that is not what i want. – Muhammad Umer Sep 07 '13 at 19:50
  • 2
    so noway to split them into multiple lines – aWebDeveloper Jan 29 '14 at 18:53
  • 2
    transform:translate(100px,100px) rotate(45deg) translate(100px,100px) rotate(45deg); equals transform:translate(200px,200px) rotate(90deg) ,the last one will add – bigCat Mar 17 '15 at 14:47
  • 1
    You may need to include a prefix for the transform to work in all browsers. Please see [this post](http://stackoverflow.com/a/25110511/2065702) for more information – Zach Saucier Mar 14 '16 at 18:50
  • Keep in mind multiple transform one line directives are **executed from left to right** - this: `transform: scale(1,1.5) rotate(90deg);` and : `transform: rotate(90deg) scale(1,1.5);` will **not** produce the same result: https://jsfiddle.net/852hzq9w/ – jave.web Jan 10 '19 at 08:09
  • 4
    @jave.web, You meant **right to left**, correct? For `transform: scale(1,1.5) rotate(90deg);`, the rotate would happen before the scale. – Jargs Jan 16 '19 at 19:03
53

I'm adding this answer not because it's likely to be helpful but just because it's true.

In addition to using the existing answers explaining how to make more than one translation by chaining them, you can also construct the 4x4 matrix yourself

I grabbed the following image from some random site I found while googling which shows rotational matrices:

Rotation around x axis: Rotation around x axis
Rotation around y axis: Rotation around y axis
Rotation around z axis: Rotation around z axis

I couldn't find a good example of translation, so assuming I remember/understand it right, translation:

[1 0 0 0]
[0 1 0 0]
[0 0 1 0]
[x y z 1]

See more at the Wikipedia article on transformation as well as the Pragamatic CSS3 tutorial which explains it rather well. Another guide I found which explains arbitrary rotation matrices is Egon Rath's notes on matrices

Matrix multiplication works between these 4x4 matrices of course, so to perform a rotation followed by a translation, you make the appropriate rotation matrix and multiply it by the translation matrix.

This can give you a bit more freedom to get it just right, and will also make it pretty much completely impossible for anyone to understand what it's doing, including you in five minutes.

But, you know, it works.

Edit: I just realized that I missed mentioning probably the most important and practical use of this, which is to incrementally create complex 3D transformations via JavaScript, where things will make a bit more sense.

Jeff
  • 12,555
  • 5
  • 33
  • 60
  • 4
    The "random site" at mines.edu is unfortunately now a dead link. – Matt Sach Feb 24 '15 at 10:18
  • 1
    As is the 9elements link :( – Matt Sach Feb 24 '15 at 11:09
  • @matt thanks for that, I'llsee if I can come up with some better links later today. – Jeff Feb 24 '15 at 19:14
  • 1
    @MattSach Ok, apparently "later today" for me means "six months later", but at least the 9elements link is fixed (someone else fixed the random sites link with Wayback, and I followed their lead.) – Jeff Aug 18 '15 at 00:53
  • 1
    I also made [this](https://rawgit.com/alexanderdickson/Transformation-Matrix/master/index.html) to help you understand them. – alex Sep 24 '15 at 06:35
  • 14
    this truly doesn't fit into this topic – user151496 Dec 16 '15 at 17:39
  • @user151496 yeah you're largely right. The main SO answer part is that you can do it, the rest is just there to be helpful. – Jeff Dec 16 '15 at 18:12
  • This may be important for those trying to animate transformations via `@keyframes`. Chromium71 doesn't appear to be able to handle animating (rather than transitioning) multiple transformations, but presumably could animate a single transformational matrix. – EoghanM Feb 07 '19 at 10:28
  • Implementation and demo: https://stackoverflow.com/questions/15133977/how-to-calculate-svg-transform-matrix-from-rotate-translate-scale-values/50433377#50433377 – Eduard Kolosovskyi Aug 07 '19 at 05:45
39

You can also apply multiple transforms using an extra layer of markup e.g.:

<h3 class="rotated-heading">
    <span class="scaled-up">Hey!</span>
</h3>
<style type="text/css">
.rotated-heading
{
    transform: rotate(10deg);
}

.scaled-up
{
    transform: scale(1.5);
}
</style>

This can be really useful when animating elements with transforms using Javascript.

richtelford
  • 511
  • 4
  • 4
23

You can apply more than one transform like this:

li:nth-of-type(2){
    transform : translate(-20px, 0px) rotate(15deg);
}
isherwood
  • 58,414
  • 16
  • 114
  • 157
geekme
  • 294
  • 2
  • 4
8

Some time in the future, (now available, see updates below) we can write it like this:

li:nth-child(2) {
    rotate: 15deg;
    translate:-20px 0px;        
}

This will become especially useful when applying individual classes on an element:

<div class="teaser important"></div>

.teaser{rotate:10deg;}
.important{scale:1.5 1.5;}

This syntax is defined in the in-progress CSS Transforms Level 2 specification, but can't find anything about current browser support other then chrome canary. Hope some day i'll come back and update browser support here ;)

Found the info in this article which you might want to check out regarding workarounds for current browsers.

UPDATE: feature has landed in firefox 72

UPDATE: now available in chrome 104, edge 104, safari 14.1, see https://web.dev/css-individual-transform-properties/#:~:text=support%20these%20properties.-,Browser%20support,-%3A

schellmax
  • 5,678
  • 4
  • 37
  • 48
  • Debatable if safe to use now. Only if you want to exclude 2% of users globally (those using older safari versions). https://caniuse.com/mdn-css_properties_rotate – Mark Fisher Jan 04 '23 at 15:52
4

Lesson I`ve learnt.

If you are using style's React css, don't include semicolons, even in the end of it because it is included automatically and internally by React.

Just like:

style={                             
  transform: "rotate(90deg) scaleX(-1)",
}

Luis Febro
  • 1,733
  • 1
  • 16
  • 21
3

It's an old question but turned out to be very relevant to me recently. I found 'transform: matrix(..)' more convenient to use. So for the issue in question, the below example applies ~15deg rotation and translation of 20px to the right (for convenience) on the x-axis.

.matrixTransform {
    transform-origin: top left;
    transform: matrix(0.965,0.258,-0.258,0.965,20,0);
    font-size: 30px;
}
.combinedTransform {
    transform-origin: top left;
    transform: rotate(15deg) translateX(20px);
    font-size: 30px;
}
<div class=matrixTransform>A</div>
<div class=combinedTransform>B</div>

From what I gather this particular transform uses initial 4 parameters to represent transformations e.g. scale, rotate. And seem to be in rows by columns order. The remaining two are translations in the x and y axis respectively. I found Wolfram Alpha cheat sheet (calculator) very useful.

klestor
  • 31
  • 2
1

Just start from there that in CSS, if you repeat 2 values or more, always last one gets applied, unless using !important tag, but at the same time avoid using !important as much as you can, so in your case that's the problem, so the second transform override the first one in this case...

So how you can do what you want then?...

Don't worry, transform accepts multiple values at the same time... So this code below will work:

li:nth-child(2) {
  transform: rotate(15deg) translate(-20px, 0px); //multiple
}

If you like to play around with transform run the iframe from MDN below:

<iframe src="https://interactive-examples.mdn.mozilla.net/pages/css/transform.html" class="interactive  " width="100%" frameborder="0" height="250"></iframe>

Look at the link below for more info:

<< CSS transform >>

Community
  • 1
  • 1
Alireza
  • 100,211
  • 27
  • 269
  • 172
0

Transform Rotate and Translate in single line css:-How?

div.className{
    transform : rotate(270deg) translate(-50%, 0);    
    -webkit-transform: rotate(270deg) translate(-50%, -50%);    
    -moz-transform: rotate(270deg) translate(-50%, -50%);    
    -ms-transform: rotate(270deg) translate(-50%, -50%);    
    -o-transform: rotate(270deg) translate(-50%, -50%); 
    float:left;
    position:absolute;
    top:50%;
    left:50%;
    }
<html>
<head>
</head>
<body>
<div class="className">
  <span style="font-size:50px">A</span>
</div>
</body>
</html>
Vinkal
  • 9
  • 2