CSS Transforms
Transitions taught you how long a change should take. Transforms teach you where the pixels go: slide a chip sideways, spin a loader icon, scale a badge on hover — usually without pushing siblings around the way margin or top would.
What transform changes
transform applies a 2D (or later 3D) mapping to an element’s rendered box. The element still occupies its original layout slot unless something else (like a width change) moves the flow. That makes translate() and friends ideal for micro-motion: hovers, toggles, and small corrections.
One property, many functions — comma-separated lists are not allowed inside a single transform value, but you chain functions in one declaration: transform: translateX(1rem) rotate(8deg) scale(1.05);
Core 2D functions
📊 2D transform functions at a glance
| Function | Typical job |
|---|---|
translate(x, y) / translateX / translateY |
Move visually without reflow drama |
rotate(angle) |
Spin icons, chevrons, loaders (deg, turn) |
scale(x, y) / scale(n) |
Grow/shrink hover emphasis; keep values modest |
skew(x, y) |
Rare tilt — easy to overuse; prefer small angles |
Angles use deg or turn. Percentages in translate() are relative to the element’s own size — handy for centering tricks paired with position: absolute patterns you already know.
Translate first — the everyday move
When you only need a nudge, reach for translate before top or margin. Browsers can often promote transformed layers to the compositor, which keeps motion smoother — especially when you add a transition from the previous lesson.
.chip {
display: inline-block;
padding: 0.35rem 0.75rem;
border-radius: 999px;
background: #e0e7ff;
color: #1e3a8a;
transition: transform 0.2s ease, background-color 0.2s ease;
}
.chip:hover,
.chip:focus-visible {
transform: translateY(-0.15rem);
background: #c7d2fe;
}
The chip lifts visually; its line box in the document stays put. Compare that to adding negative margin-top on hover — neighbors jump.
Rotate and scale together
Icons and badges often combine a small scale with a rotate on interaction. Keep angles tight so the UI stays professional, not carnival.
.badge {
display: inline-flex;
align-items: center;
gap: 0.35rem;
font-size: 0.875rem;
transition: transform 0.25s ease;
}
.badge:hover {
transform: scale(1.06);
}
.chevron {
display: inline-block;
transition: transform 0.2s ease;
}
.menu-open .chevron {
transform: rotate(180deg);
}
scale(1.06) reads as emphasis; scale(2) reads as a mistake. Rotation at 180deg is a clear “opened” state for a disclosure chevron — pair it with class toggles in HTML/JS later.
transform-origin — where motion hinges
By default, transforms pivot around the center of the box. transform-origin moves that pivot — bottom-left for a door swing, top center for a flip feel, 50% 100% for a tab that bends from its base.
.panel-tilt {
transform-origin: 50% 100%;
transition: transform 0.35s ease;
}
.panel-tilt.is-open {
transform: rotateX(12deg);
}
This example uses a mild rotateX hint (still transform vocabulary). Full 3D stages live in the optional 3D Transforms session — here, origin is the lesson: same angle feels different when the pivot moves.
Pair with transitions; avoid layout props
Put transition on the base rule and animate transform (and opacity) for hover/open states — not width/height/top. Honor prefers-reduced-motion: reduce by skipping or shortening spin/scale flourishes.
Try it yourself
- Hover-lift a button with
translateY(-0.2rem)plus a shorttransition— then try the same nudge withmargin-topand watch neighbors shift. - Rotate a chevron
180degwhen a parent gets.is-open; keep duration around0.2s. - Set
transform-origin: left centeron a card and apply a smallrotate()— compare with default center origin. - Chain
translateX(0.5rem) scale(1.04)on a tag hover in onetransformdeclaration. - Emulate
prefers-reduced-motion: reduceand remove non-essential scale/spin.
Common mistakes
- Using
top/left/marginfor hover “lift” whentranslatewould keep layout stable transform: rotate(45deg)on large wrappers — motion sickness on whole pages- Forgetting
transform-originon hinged UI — everything spins from the middle scale(0)to hide content without a plan to restore accessibility/focus- Jumping to heavy 3D perspective when a 2D translate + opacity is enough
Summary
transformmaps the painted box; flow usually stays unless layout properties change- Use translate, rotate, scale, and skew thoughtfully; chain functions in one transform
transform-origincontrols the pivot — critical for believable motion- Pair transform with transitions; prefer transform/opacity over layout thrash
- Next in Effects & Motion: CSS Animations (
@keyframes)
🧠 Test Your Knowledge
Test Your Knowledge
Challenge yourself with this interactive quiz and see how well you understand the topic
📝 Instructions
- Read each question carefully
- Select the best answer for each question
- You can retake the quiz as many times as you want
- Your progress will be shown at the top