The CSS transform property
The CSS transform property visually moves, rotates, scales or skews an element using functions like translate(), rotate(), scale() and skew(). Crucially it does not affect the layout around the element — neighbors stay put — and it is cheap for the browser to animate, which is why hover effects and transitions lean on it.
Overview
transform changes how an element is painted — its position, angle, size or slant — without changing where it sits in the document. That last part is the key: a transformed element is moved visually, but the space it originally occupied is preserved, so nothing else on the page shifts to follow it.
You apply it through functions. translate(x, y) nudges an element along; rotate(15deg) spins it; scale(1.1) grows it; skew() slants it. You can chain several in one declaration — transform: translateY(-4px) scale(1.05) is a classic "lift on hover" — and they apply left to right.
Two reasons it is everywhere in modern CSS: it is hardware-accelerated, so animating it (and opacity) stays smooth where animating layout properties would stutter; and it leaves layout untouched, so you can move and scale things on hover without the page reflowing around them. The transform-origin property lets you change the pivot point when the default center is not what you want.
Syntax
selector {
transform: function(value);
}
/* lift and grow on hover */
.card:hover {
transform: translateY(-4px) scale(1.02);
}
Values
The transform property accepts the values below. Every property also accepts the CSS-wide keywords inherit, initial, revert and unset.
| Value | Description |
|---|---|
translate(x, y) |
Moves the element by x and y without affecting layout. translateX / translateY too. |
rotate(angle) |
Rotates the element, e.g. rotate(15deg). Negative angles go anticlockwise. |
scale(n) |
Resizes the element, e.g. scale(1.1) for 110%. scaleX / scaleY for one axis. |
skew(angle) |
Slants the element along the X and/or Y axis. |
multiple |
Chain functions: transform: translateY(-4px) scale(1.05). |
Example
<style>
.row { display: flex; gap: 18px; justify-content: center; padding: 24px; font: 600 13px system-ui, sans-serif; }
.row div { width: 80px; height: 80px; background: #1c7ce9; color: #fff; display: flex; align-items: center; justify-content: center; border-radius: 10px; text-align: center; }
.a { transform: rotate(-8deg); }
.b { transform: scale(1.15); }
.c { transform: translateY(-10px); }
</style>
<div class="row">
<div class="a">rotate</div>
<div class="b">scale</div>
<div class="c">translate</div>
</div>
Best practices
- Animate
transformand opacity for smooth motion — they run on the GPU, unlike animating width, height or position. - Use
transformfor hover lifts and micro-interactions because it does not reflow the page when the element moves. - Set
transform-originwhen you need to rotate or scale around a corner or edge instead of the center. - Honor
prefers-reduced-motionand pair transforms with a transition so changes ease rather than snap.
Accessibility
Transforms are how a lot of motion gets built, so they intersect with the needs of people who are sensitive to movement. Large or repeated transforms — spinning, zooming, parallax — can trigger nausea or distraction. Wrap anything beyond a subtle hover effect in a @media (prefers-reduced-motion: reduce) check and dial it back for users who have asked their system to limit motion.
A subtler point: a transformed element still occupies its original box for layout and hit-testing, but its visible position can drift away from where keyboard focus or a tooltip expects it. Avoid using large translations to reposition interactive controls; move them in the markup or with layout instead.
Frequently asked questions
How do I rotate an element in CSS?
transform: rotate(15deg). Positive angles rotate clockwise, negative anticlockwise. The element pivots around its center unless you change transform-origin.Does transform affect the layout?
Why is transform good for animation?
transform (and opacity) are hardware-accelerated and do not trigger layout, so the browser can animate them smoothly at 60fps.How do I combine multiple transforms?
transform: translateY(-4px) scale(1.05) rotate(2deg). They apply from left to right.