The transform property allows you to visually manipulate an element by skewing, rotating, translating, or scaling:

.element {
  width: 20px;
  height: 20px;
  transform: scale(20);

Even with a declared height and width, this element will now be scaled to twenty times its original size:

See the Pen Transform explanation by CSS-Tricks (@css-tricks) on CodePen.

Giving this function two values will stretch it horizontally by the first and vertically by the second. In the example below the element will now be twice the width but half the height of the original element:

.element {
  transform: scale(2, .5);

Or you can be more specific without using the shorthand function:

transform: scaleX(2);
transform: scaleY(.5);

But scale() is just one of many transform functions that are available:


  • scale(): affects the size of the element. This also applies to the font-size, padding, height, and width of an element, too. It’s also a a shorthand function for the scaleX and scaleY functions.
  • skewX() and skewY(): tilts an element to the left or right, like turning a triangle into a parallelogram. There is no shorthand skew property.
  • translate(): moves an element sideways or up and down.
  • rotate(): rotates the element clockwise from its current position.
  • matrix(): a function that is probably not intended to be written by hand, but combines all transforms into one.
  • perspective(): doesn’t affect the element itself, but affects the transforms of descendent elements' 3D transforms, allowing them all to have a consistent depth perspective.


.element {
  transform: skewX(25deg);

.element {
  transform: skewY(25deg);

The skewX and skewY transform functions tilt an element one way or the other. Remember: there is no shorthand property for skewing an element, so you’ll need to use both functions. In the example below, we can skew a 100px x 100px square to the left and right with skewX:

See the Pen Transform explanation by CSS-Tricks (@css-tricks) on CodePen.

Whilst in this example we can skew an element vertically with with skewY:

See the Pen Transform explanation by CSS-Tricks (@css-tricks) on CodePen.


.element {
  transform: rotate(25deg);

This rotates an element clockwise from its original position, whilst a negative value would rotate it in the opposite direction. Here’s a simple animated example where a square continues to rotate 360 degrees every three seconds:

See the Pen Transform explanation by CSS-Tricks (@css-tricks) on CodePen.

We can also use the rotateX, rotateY and rotateZ functions, like so:

See the Pen Transform explanation by CSS-Tricks (@css-tricks) on CodePen.


.element {
  transform: translate(20px, 10px);

This transform function moves an element sideways, or up and down. Why not just use top/left/bottom/right? Well, it's a bit confusing at times. I would think of those as layout/positioning (they have better browser support anyway) and this as a way to move those things around as part of a transition or animation.

These values would be any length value, like 10px or 2.4em. One value will move the element to the right (negative values to the left). If a second value is provided, that second value will move it down (negative values up). Or, you can get specific:

transform: translateX(value);
transform: translateY(value);

It’s important to note that an element using transform will not cause other elements to flow around it. By using the translate function below and nudging the green square out of its original position, we’ll notice how the surrounding text will remain fixed in place, as if the square is a block element:

See the Pen Transform explanation by CSS-Tricks (@css-tricks) on CodePen.

It’s also worth noting that translate will be hardware accelerated if you want to animate that property, unlike position: absolute.

Multiple values

With a space-separated list you can add multiple values to the transform property:

.element {
  width: 20px;
  height: 20px;
  transform: scale(20) skew(-20deg);

It’s worth noting that there is an order in which these transforms will be carried out, in the example above `skew` will be performed first and then the element will be scaled.


The matrix transform function can be used to combine all transforms into one. It's a bit like transform shorthand, only I don't believe it's really intended to be written by hand. There are tools out there like The Matrix Resolutions, which can convert a group of transforms into a single matrix declaration. Perhaps in some situations this can reduce file size, although author-unfriendly micro optimizations like that are likely not worth your time.

For the curious, this:

rotate(45deg) translate(24px, 25px)

can also be represented as:

matrix(0.7071067811865475, 0.7071067811865476, -0.7071067811865476, 0.7071067811865475, -0.7071067811865497, 34.648232278140824)

3D Transforms

Most of the above properties have 3D versions of them.

translate3d(x, y, z)

The third value in translate3d or the value in translateZ moves the element toward the viewer, negative values away.

scale3d(sx, sy, sz)

The third value in scale3d or the value in scaleZ affects the scaling along the z-axis (e.g. the imaginary line coming straight out of the screen).

rotate3d(x, y, z)

rotateX and rotateY will rotate an element in 3D space around those axises. rotate3d allows you to specify a point in 3D space in which to rotate the element around.


A way to programmatically describe a 3D transform in a 4x4 grid. Nobody will ever hand write one of these, ever.


This value doesn't affect the element itself, but it affects the transforms of descendent elements' 3D transforms, allowing them to all have a consistent depth perspective.

More Information

Related Properties

Browser Support

2D Transforms

Chrome Safari Firefox Opera IE Android iOS
Any 3.1+ 3.5+ 10.5+ 9+ 4.1+ At least 4

3D Transforms

Chrome Safari Firefox Opera IE Android iOS
10+ 4+ 12+ none 10+ 4.1+ 5+

Vendor prefixes

.element {
  -webkit-transform: value;
  -moz-transform:    value;
  -ms-transform:     value;
  -o-transform:      value;
  transform:         value;


  1. User Avatar
    Permalink to comment#

    thanks a lot.
    3D Transforms Will be usefull…

  2. User Avatar

    Hi, I dont understand the ScaleZ, in transform, if u change the scaleX(2) it will scale the width, but we have not the depth value of the element so scaleZ(3) meanse 3 * 0 = 0

    so scaleZ has no effect on element

  3. User Avatar
    Martin Ansty
    Permalink to comment#

    A quick note that rotate3d() actually takes 4 arguments like so:

    rotate3d(x, y, z, a)

    Where the first three arguments describe a point in 3d space around which you wish to rotate; and the fourth an angle by which to rotate the element.

    • User Avatar
      Martin Ansty
      Permalink to comment#

      In actual fact the first three arguments are a vector describing the axis of rotation. ie they take a unitless <number> not a <length>

  4. User Avatar
    Permalink to comment#
  5. User Avatar
    Patrick Bruckner
    Permalink to comment#

    -webkit-transform: rotate(-2deg);
    This will not occupy its original space in Webkit-Browsers… Causes some problems for me

  6. User Avatar
    Permalink to comment#

    Is there a way to scale the text inside that box as well?

    • User Avatar
      Permalink to comment#

      Yeah we can just take an element like p. then generate code.
      -moz-transform: skewX(12deg) skewY(32deg);
      -webkit-transform: skewX(12deg) skewY(32deg);
      -o-transform: skewX(12deg) skewY(32deg);
      -ms-transform: skewX(12deg) skewY(32deg);
      transform: skewX(12deg) skewY(32deg);

  7. User Avatar
    gujrit singh

    Facing problem while applying transform(translation) on button:hover ?? Does anyone have solution or faced similar problem.??
    This is coding of my css file

                cursor: pointer;
                transform: translate(3px,3px);
                box-shadow: none;    
    • User Avatar
      Permalink to comment#

      Transform is not available in all browsers becouse its new css property. So you must do it cross browser.
      Use -moz-transform for Mozila FireFox, -webkit-transform for Safari,Chrome…

  8. User Avatar
    Permalink to comment#

    Why this 2 codes are the same? I agree about rotate in both but tanslate in matrix must be 24,25 instead of -0.7071067811865497, 34.648232278140824.

      1) rotate(45deg) translate(24px, 25px) 
      2)matrix(0.7071067811865475, 0.7071067811865476, -0.7071067811865476, 0.7071067811865475, -0.7071067811865497, 34.648232278140824)

    1) rotate(45deg) translate(24px, 25px)
    2) matrix(0.7071067811865475, 0.7071067811865476, -0.7071067811865476, 0.7071067811865475, -0.7071067811865497, 34.648232278140824)

  9. User Avatar
    Permalink to comment#

    2D Transforms work in IE 9+ , works through prefix -ms-

  10. User Avatar
    Permalink to comment#

    Can you give me a way to 3d rotate in Adobe Flash CS3 .It can be some code , etc..

  11. User Avatar
    Ahmed Mahmoud
    Permalink to comment#

    really cool :)
    thanks for your time

  12. User Avatar
    Ruud Bakker

    It seems that a positive value of skewX is counter-clockwise, as opposed to the values for rotateX, which are clockwise. Very strange I think, so your example of skewX(25deg) is wrong.

    • User Avatar
      Amar Chhetri
      Permalink to comment#

      Hello Ruud, do you have the answer why positive value of skewX is counter-clockwise instead of clockwise. I cudnt get it why it works that way. And Hello Chris, hoping for ur answer.

  13. User Avatar
    Permalink to comment#

    The scale property makes the image scale from wish and heighthe zero.

    I am using scroll to scale up or down. But as soon as I start scrolling the image goes to probably one pixel and scales according to that.

    Is there a 0 to 100 property to manipulate “scale” to make it like 100 to 110?

  14. User Avatar
    Zach Green
    Permalink to comment#

    It’s worth noting that there is now a skew shorthand, à la skew(10deg, 10deg).

  15. User Avatar
    Amar Chhetri
    Permalink to comment#

    As shown in Skew section above, skewX(25deg) tilts it towards the right. And that makes sense to me(But we are both wrong here Chris). Because actually it tilts it towards the left. I could not relate it to the co-ordinate system, positive deg should have actually tilted it towards the right.

  16. User Avatar
    Vivek Shetye
    Permalink to comment#

    Actually my qusetion is off topic but can u help me with that arrow in your active menu…
    The arrow that comes down when HTML or SCSS or Result is active…
    Plz help..
    Thank you in advance… :)

  17. User Avatar
    Loïc Giraudel
    Permalink to comment#

    skewX() and skewY(): tilts an element to the left or right, like turning a triangle into a parallelogram.

    => a square into a parallelogram, not a triangle (or I don’t get it).

  18. User Avatar
    Permalink to comment#

    It’s strange how scale affects translate if you add them in the wrong order.
    If I write:
    transform: scale(.05, .05) translateX(100px);
    …it only moves 5 pixels
    It’s like the distance has increased or the translate pixels are scaled as well.

    However if I write like this:
    transform: translateZ(-2000px) translateX(400px);
    …it gets smaller but still moves 400px from it’s original place at the screens depth.

    In case 2 I would have understood if translateX was a horizontal movement in relation to the new distance from the screen, but scale doesn’t have anything to do with perspective, right?

    • User Avatar
      Johan Kohlin
      Permalink to comment#

      Since this thread is still alive I might as well try once more to see if anyone has a logical explanation for the question above.
      How come the translate value get “scaled” if I scale down an element before I translate it, but not if I move it way back on the Z axis?

    • User Avatar
      Permalink to comment#

      I’ll take a stab at this. I think, in case 1, its because you’ve scaled down to 5% and then applied a transformation of 100px. so 5% of it is 5px. if you changed the order of the two transformations, you’ll get your desired effect.

    • User Avatar
      Permalink to comment#

      I’m pretty sure it has something to do with the order of transformations. They mentioned it briefly in the article above, but only stated that skew is applied before scale. I think the order is [skew -> scale -> translate].

  19. User Avatar
    Permalink to comment#

    A really useful npm plugin gulp-autoprefixer, gulp-autoprefixer saves you having to manually add browser specific properties to your css.

  20. User Avatar
    Travis Hedrick
    Permalink to comment#

    Hey guys! Anyone care to tell me why this doesn’t rotate from the center like the default specification states…. I’m stumped

    • User Avatar
      Travis Hedrick
      Permalink to comment#

      FYI, Changing transform-origin has no effect either….

    • User Avatar

      Just guessing here, but it’s probably applying the scaling first, then rotating it. The change in scale is probably changing the center of rotation.

  21. User Avatar
    Permalink to comment#

    That’s odd, how does Opera have no 3d support when it is based on Chrome?

Posting Code

You may write comments in Markdown. This makes code easy to post, as you can write inline code like `<div>this</div>` or multiline blocks of code in triple backtick fences (```) with double new lines before and after.

Code of Conduct

Absolutely anyone is welcome to submit a comment here. But not all comments will be posted. Think of it like writing a letter to the editor. All submitted comments will be read, but not all published. Published comments will be on-topic, helpful, and further the discussion or debate.

Want to tell us something privately?

Feel free to use our contact form. That's a great place to let us know about typos or anything off-topic.

Submit a Comment