Loading...

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 nudge on hover

css
.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 pop and chevron spin

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

Hinge from bottom edge with transition

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

  1. Hover-lift a button with translateY(-0.2rem) plus a short transition — then try the same nudge with margin-top and watch neighbors shift.
  2. Rotate a chevron 180deg when a parent gets .is-open; keep duration around 0.2s.
  3. Set transform-origin: left center on a card and apply a small rotate() — compare with default center origin.
  4. Chain translateX(0.5rem) scale(1.04) on a tag hover in one transform declaration.
  5. Emulate prefers-reduced-motion: reduce and remove non-essential scale/spin.

Common mistakes

  • Using top/left/margin for hover “lift” when translate would keep layout stable
  • transform: rotate(45deg) on large wrappers — motion sickness on whole pages
  • Forgetting transform-origin on 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

  • transform maps the painted box; flow usually stays unless layout properties change
  • Use translate, rotate, scale, and skew thoughtfully; chain functions in one transform
  • transform-origin controls 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

Ready to Start

Test Your Knowledge

Challenge yourself with this interactive quiz and see how well you understand the topic

❓
6
Questions
🎯
70%
To Pass
♾️
∞
Time
🔄
∞
Attempts

📝 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