The Lodge is members-only design/dev videos and Office Hours.

Next Office Hours Session: "Implementing an SVG Icon System" Nov 30 - 6:00 PM Eastern


Last updated on:

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. shahryar
    Permalink to comment#

    thanks a lot.
    3D Transforms Will be usefull…

  2. Cameron

    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. 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.

    • 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>

    Permalink to comment#
  5. 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. Dimi
    Permalink to comment#

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

    • Lakshya
      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. 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;    
    • Victor_S
      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. Victor_S
    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. fdkitamory
    Permalink to comment#

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

  10. Nishant
    Permalink to comment#

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

  11. Ahmed Mahmoud
    Permalink to comment#

    really cool :)
    thanks for your time

  12. 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.

    • 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. Varun
    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. Zach Green
    Permalink to comment#

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

  15. 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. 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. 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. Johan
    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?

Leave a Comment

Posting Code

We highly encourage you to post problematic HTML/CSS/JavaScript over on CodePen and include the link in your post. It's much easier to see, understand, and help with when you do that.

Markdown is supported, so you can write inline code like `<div>this</div>` or multiline blocks of code in in triple backtick fences like this:

  function example() {
    element.innerHTML = "<div>code</div>";

There's a whole bunch of content on CSS-Tricks.

Search for Stuff   •   Browse the Archives

Get the Newsletter ... or get the RSS feed