Skip to content
Laviyx Learn

Try

CSS course menu

CSS Transforms: translate, rotate, scale, skew and transform-origin

Learn CSS transforms with live examples: translate, rotate, scale and skew, combining transforms and why order matters, transform-origin, the individual translate, rotate and scale properties, and 3D transforms with perspective.

Intermediate5 min readUpdated
On this page

The transform property moves, rotates, scales and skews an element visually, without affecting the layout around it: neighbouring elements stay where they are, as if the element had not changed.

The four basic transforms#

CSS
.stage { display: flex; gap: 30px; padding: 30px; }
.b { width: 70px; height: 70px; display: grid; place-items: center; background: #2f5fe0; color: white; font: 12px monospace; border-radius: 6px; }
.ghost { outline: 2px dashed #bbb; }
HTML
<div class="stage">
  <div class="ghost"><div class="b" style="transform: translate(20px, 20px)">translate</div></div>
  <div class="ghost"><div class="b" style="transform: rotate(25deg)">rotate</div></div>
  <div class="ghost"><div class="b" style="transform: scale(1.3)">scale</div></div>
  <div class="ghost"><div class="b" style="transform: skewX(-15deg)">skew</div></div>
</div>
Result

The dashed outlines show where each box would normally be.

FunctionExampleEffect
translate(x, y)translate(20px, -10px)Move. Percentages are relative to the element's own size.
rotate(angle)rotate(45deg), rotate(0.25turn)Rotate clockwise (negative is anticlockwise)
scale(x, y)scale(1.2), scale(-1, 1)Resize; -1 mirrors
skew(x, y)skewX(10deg)Slant

Combining transforms#

List several functions separated by spaces. They are applied from right to left, which means the order changes the result:

CSS
.stage { position: relative; height: 140px; }
.b { position: absolute; top: 50px; left: 20px; width: 60px; height: 40px; background: #e8590c; opacity: 0.9; }
.one { transform: translateX(120px) rotate(45deg); }
.two { transform: rotate(45deg) translateX(120px); background: #2f9e44; }
HTML
<div class="stage">
  <div class="b one"></div>
  <div class="b two"></div>
</div>
Result

The orange box rotates and then moves right. The green box moves along its rotated axis, so it travels diagonally.

transform-origin#

Rotation and scaling happen around the element's centre by default. transform-origin moves that point:

CSS
.stage { display: flex; gap: 70px; padding: 30px 40px; }
.b { width: 80px; height: 50px; background: #9b5de5; transform: rotate(30deg); }
HTML
<div class="stage">
  <div class="b" style="transform-origin: center"></div>
  <div class="b" style="transform-origin: top left"></div>
  <div class="b" style="transform-origin: bottom right"></div>
</div>
Result

Individual properties: translate, rotate, scale#

You can also use separate properties, which are easier to change independently (for example, in different states or animations):

CSS
.icon {
  translate: 0 -2px;
  rotate: 10deg;
  scale: 1.1;
}

They are applied in a fixed order (translate, then rotate, then scale) and combine with any transform value.

Transforms are visual only#

Because transforms do not change layout:

  • scaling up a card on hover does not push its neighbours away (it overlaps them instead);
  • translate is ideal for animation, since the browser does not need to recalculate layout (Transitions);
  • a transformed element creates a new stacking context and becomes the containing block for position: fixed children (z-index).

3D transforms#

Add perspective to the parent to give children depth, then rotate them around the X or Y axis:

CSS
.scene { perspective: 600px; display: flex; gap: 30px; padding: 30px; }
.card { width: 110px; height: 120px; background: linear-gradient(135deg, #2f5fe0, #9b5de5); color: white; display: grid; place-items: center; border-radius: 10px; font: 13px monospace; }
HTML
<div class="scene">
  <div class="card" style="transform: rotateY(40deg)">rotateY(40deg)</div>
  <div class="card" style="transform: rotateX(40deg)">rotateX(40deg)</div>
  <div class="card" style="transform: rotateY(-40deg)">rotateY(-40deg)</div>
</div>
Result

Smaller perspective values give a stronger effect. backface-visibility: hidden and transform-style: preserve-3d are used to build flip cards.

Practice#

Practice exercise

Create a "notification bell" icon (use the 🔔 emoji in a span) that rotates back and forth slightly around its top centre when its button is hovered: rotate it to 15deg on hover with a 0.2s transition and transform-origin: top center.

Show solution
CSS
.bell-btn { font-size: 28px; background: none; border: 1px solid #ddd; border-radius: 10px; padding: 6px 12px; }
.bell { display: inline-block; transform-origin: top center; transition: transform 0.2s ease-out; }
.bell-btn:hover .bell, .bell-btn:focus-visible .bell { transform: rotate(15deg); }
HTML
<button class="bell-btn" type="button" aria-label="Notifications"><span class="bell" aria-hidden="true">🔔</span></button>
Result

transform does not work on non-replaced inline elements, so the span is made inline-block. A continuous swing would need a keyframe animation (next lesson).

Key takeaway#

Finished this lesson?