CSS Transform and Transition

CSS3 transform and transition properties have made it very easy for front-end developers to create, move, reshape, rotate, scale, and translate elements within a coordinate, without using JavaScript. The addition of these properties to CSS3 shifted the web from a static, text-like nature to a more dynamic look, loaded with visual effects.

Transform is a property that allows an element to change its shape, size, and position. It takes five values – rotation, translation, skew, scale, and matrix. A transition property controls the speed and duration of a transformation, making it smooth and linear.
The transform and transition are stand-alone properties, but they usually work together to create a consistent and straightforward movement of elements within a web page. Without transition, transformation effects take place immediately and abruptly.
CSS transform and transition often reside under advanced CSS. Though they are not used as often as text properties, there is nothing special about them. They still follow the standard CSS rule-set and syntax. Understanding how to manipulate them on-screen within a given coordinate is where the trick lies.


Using CSS transform changes the state, position and structure of an element especially during events, such as mouseover. It allows you to translate, skew, rotate, and skew elements within the X and Y-axis. CSS transform has two types, 2D (default transform) and 3D transforms. For 3D, transformation can happen within the X, Y, and Z-axis.
The syntax for transform is quite simple.

transform: rotate(90deg); 

CSS transform has two properties – transform and transform-origin. The latter is responsible for transforming elements and for the element placement in the x, y, and z-axis. The units for transform-origin include left, right, center, top, bottom, and %.

transform: rotate(90deg); 
transform-origin: 30% 20%;

The first unit, 30%, is for the x-axis, while the second 20% is for the y-axis. In shorthand, the transform and transform-origin property can merge on the same line.

transform: rotate(40deg) 20% 30%; 


Rotate() is a value attached to the transform property. It rotates an element clockwise or counter-clockwise according to the degree value. The rotate value takes a parameter in deg. A positive deg will move an element in a clockwise manner, and a negative deg will move the element in a counter-clockwise fashion.

transform: rotate(-40deg) /* this moves 40deg counter clockwise */


This moves an element from its current position to another position according to the X and Y-axis parameters.

transform: translate (100px, 90px); 

The first value, 100, moves the element to the right, while the second one, 90, moves the element down from its current position. If the same values were negative, -100 and -90, it will move the element 100px to the left and 90px upward from its current position.
The axis can also be specified in the code declaration and given a single value.

transform: translateY(20px); 
transform: translateX(30px);


The skew() value skews an element along the X or Y-axis.

transform: skew(20deg, 40deg); 

You could also define the axis like this:

transform: skewX(10deg);
transform: skewY(10deg);


Scale() increases or decreases the height and width of an element.

transform: scale(3);

This makes the element to be three times the original size. The scale value takes only two parameters—the first being for the component's width and the second for the height.

transform: scale(2, 5) /* this will make the width twice the original size and the height 5 times it's original size. */

The scaleX increases/decreases only the width of an element, while the scaleY increases/decreases the element's height.
You can specify all the transform properties on one line like this,

Transform: translate(10px, 10px) scale (2) rotate(40deg) skew(3deg, 10deg)

Simple Click-Effect On A Button Using Transform

Check out the effect when you click on this button


button { 
  padding: 10px 15px;
  font-size: 20px;
  font-family: "Lucida Console", Courier, monospace;
  text-align: center;
  outline: none;
  cursor: pointer;
  color: #ffffff;
  background-color: #592720;
  border: none;
  border-radius: 15px;
  box-shadow: 0 5px #777;
button:active {
  background-color: #8b0000;
  box-shadow: 0 5px #999;
  transform: translateY(6px);   

3D Transform

3D transformations allow you to move, rotate, skew, and scale an element on three axes, X, Y, and Z. 3D transform makes use of the perspective property. When attached to an element, this property allows the element to behave as though it were in a three-dimensional space. The prospective property's value is an integer and specifies the distance from the element's origin on the z-axis. The 3D effect gives an illusion of depth.

transform: rotateZ(90deg);

3D still uses the same properties as 2D (which is the default transformation).
For a 3D demo, we will create a card, which on hover has a backface. You can use it in image galleries. The front has a picture, while the back is the description.
In addition to perspective, we will use the backface visibility property, which specifies if an element's back will show when facing the user. It works as a mirror screen.

<div class="flip-card"> 
  <div class="card-inner"> 
    <div class="card-front"> 
      <img src="https://www.telegraph.co.uk/content/dam/Travel/2020/June/florence-rooftops-italy-getty-xlarge.jpg" alt="Turkey" style="width:300px;height:300px;"> 
      <p>Learn more...</p> 
    <div class="card-back"> 
      <h3>Have you been to Turkey?</h3>  
      <p>Turkey, officially the Republic of Turkey, is a transcontinental country located mainly on the Anatolian Peninsula in Western Asia, with a smaller portion on the Balkan Peninsula in Southeastern Europe.</p> 
      <a href="">Go to official page</a> 
p, h1, h3, a { 
  font-family: "Lucida Console", Courier, monospace; 
  padding: 3px; 
  color: black; 
.flip-card { 
  background-color: transparent; 
  width: 300px; 
  height: 300px; 
  perspective: 1000px; 
   border: 10px solid #592720; 
.card-inner { 
  position: relative; 
  width: 100%; 
  height: 100%; 
  text-align: center; 
  transition: transform 0.6s; 
  transform-style: preserve-3d; 
  box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2); 
.flip-card:hover .card-inner { 
  transform: rotateY(180deg); 
.card-front, .card-back { 
  position: absolute; 
  width: 100%; 
  height: 100%; 
  -webkit-backface-visibility: hidden; 
  backface-visibility: hidden; 
.card-back { 
  background-color: #ad0000; 
  color: white; 
  transform: rotateY(180deg); 


Transition property adds time durations, delays, and timing functions to elements, allowing them to change smoothly, evenly, and progressively from one state to another. Two things must be specified when using transition – the property the transition is applied to and the duration of the effect.
Transition works alone without transform, in fact, transform is just one property of transition.

    <div>One Div</div>
  width: 200px; 
  height: 200px; 
  background-color: #ab4e52; 
  transition: background-color 2s; 
div:hover { 
  background-color: #fa0000;

The above code gradually changes the background color from a dark maroon shade to a red hue over a 2-second duration as stated in the transition declaration, when the mouse hovers over the div.
We could also change the div's width, this time with a little delay and a timing function.

    <div>One Div</div>
div { 
  width: 100px; 
  height: 100px; 
  background-color: #ab4e52; 
  transition: width, height 1s; 
  transition-delay: 3s; 
  transition-timing-function: ease; 
div:hover { 
  width: 200px; 
  height: 200px; 

In this case, when the mouse hovers over the div, the div's size is doubled. However, there's a 3-second effect before this happens. The development takes place in an 'ease' motion, which we will look at next.

Transition timing functions and delay

Transition delay causes a delay, usually in seconds before an effect takes place. Transition timing-function specifies the speed and motion of the effect. According to W3Schools,

“The transition-timing-function property can have the following values:

  • ease - specifies a transition effect with a slow start, then fast, then end slowly (this is default)
  • linear - specifies a transition effect with the same speed from start to end
  • ease-in - specifies a transition effect with a slow start
  • ease-out - specifies a transition effect with a slow end
  • ease-in-out - specifies a transition effect with a slow start and end
  • cubic-bezier(n,n,n,n) - lets you define your own values in a cubic-bezier function.”

You could add a timing function to all transition properties.
Transition shorthand takes transition property, duration, delay, and timing function in a single line. The width and height effect can be rewritten as,

transition: width 1s, height 1s ease 3s.

It takes this format. Transition-property, transition-duration, transition-timing-function, and transition-delay. Transition delay and timing-function are optional.

Creating A Rounded Image Using Transition + Transform

Check out what happens when you hover over this image

<img src="https://img.freepik.com/free-vector/beautiful-gradient-spring-landscape_23-2148448598.jpg?size=626&ext=jpg" alt="landscape" /> 
<p>This will become a rounded image just like a profile pic</p>
  width: 400px; 
  height: 400px;  
  border: 10px double #b0e0e6; 
  transition-property: border, border-radius, transform; 
  transition-duration: 2s; 
  transition-timing-function: ease-in-out; 
img:hover { 
  border: 10px groove #00b7eb; 
  border-radius: 50%; 
  transform: scale(0.6); 
  font-weight: bold;
  font-size: 20px;

NOTE: Both transform and transition still require browser support and vendor prefixes. Even though Chrome and Firefox fully support both properties, please use extra caution when adding the vendor prefixes.

transform: rotate(40deg) 
-o-transform: rotate(40deg) 
-moz-transform: rotate(40deg) 
-webkit-transform: rotate(40deg); 
-ms-transform: rotate(40deg);

The same also applies to transitions.

Why should you use transform and transitions?

CSS transforms and transitions may seem a bit too much and you may be wondering how and why you need them on a static site.

  • They add to the beauty of a site.
  • They add dynamicity to a site.
  • They make a site more interactive.

What elements need transforms and transitions?

Not all elements require visual effects, but components like images and buttons participate in the most used transform and transitions cases. Visual effects add life to these two elements and, in turn, makes the website more relatable.

Like this article? Please rate it!


Ivaylo Ivanov

Ivaylo loves Frontend implementations. He is eager to construct interfaces that users love; pixel-perfect. In his day-to-day job, he caters to anything HTML, CSS, SCSS, or JavaScript-based on the frontend side. Complexity is not a problem, he masters VueStorefront implementations equally well to simple web apps or PWAs.
Experimentation with CSS and its' capabilities is Ivo's passion. Be it animated elements, or SVG animations - he loves it!