Chapter 25: SVG Transformations
SVG: Transformations!
Imagine we’re sitting together with the code editor open, and I’m your patient teacher who’s going to explain everything about SVG transformations step by step — slowly, clearly, with lots of copy-paste examples you can try right now.
What does “transformation” mean in SVG?
A transformation changes the position, size, rotation, or skew of an SVG element (or group of elements) without changing its original coordinates.
In other words:
- You don’t rewrite all the x, y, cx, cy, width, height values
- Instead, you tell the browser: “Take this shape and move it, rotate it, scale it, slant it — but keep the original code clean”
This is extremely useful for:
- Rotating icons/arrows
- Scaling buttons on hover
- Animating movement
- Creating symmetrical designs
- Positioning complex groups easily
- Making responsive / interactive graphics
The main way to apply transformations: the transform attribute
You can put the transform attribute on almost any SVG element:
- <g> (group) ← most common — apply once to many shapes
- <rect>, <circle>, <ellipse>, <path>, <polygon>, <polyline>, <text>, <image>, etc.
- Even <svg> itself (viewport transform)
The transform value is a space-separated list of transformation functions.
The 6 most important transformation functions (2025–2026)
| Function | What it does | Syntax example | Typical use case |
|---|---|---|---|
| translate(x y) | Move horizontally (x) and vertically (y) | translate(100 50) | Shift position without changing coords |
| scale(sx [sy]) | Scale horizontally (sx) and vertically (sy) | scale(1.5) or scale(2 0.5) | Enlarge / shrink / stretch |
| rotate(a [cx cy]) | Rotate by angle a degrees (clockwise) | rotate(45) or rotate(90 100 100) | Turn icons, arrows, text |
| skewX(a) | Slant horizontally by angle a | skewX(30) | Fake perspective / italic effect |
| skewY(a) | Slant vertically by angle a | skewY(-20) | Another fake perspective style |
| matrix(a b c d e f) | Full 2D transformation matrix | matrix(1 0.5 0 1 0 0) | Advanced / combined transforms |
Important rule about order Transformations are applied from right to left (the last one in the list is applied first).
|
0 1 2 3 4 5 6 |
transform="translate(100 50) rotate(45) scale(1.5)" |
→ First scale → then rotate → then translate
Example 1 – Simple translate (move without changing coordinates)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<svg width="500" height="300" style="border:1px solid #eee; background:#f9f9f9;"> <!-- Original position --> <circle cx="80" cy="80" r="50" fill="#4CAF50" /> <!-- Moved 200 right and 100 down --> <circle cx="80" cy="80" r="50" fill="#2196F3" transform="translate(200 100)" /> <text x="250" y="180" font-size="28" text-anchor="middle"> Blue circle moved — same original cx/cy! </text> </svg> |
Example 2 – Rotate around center (very common pattern)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<svg width="300" height="300"> <!-- Center point marked --> <circle cx="150" cy="150" r="5" fill="red"/> <!-- Original arrow pointing right --> <polygon points="150,140 220,150 150,160" fill="#F44336"/> <!-- Rotated 45°, 90°, 135° around center --> <polygon points="150,140 220,150 150,160" fill="#673AB7" transform="rotate(45 150 150)"/> <polygon points="150,140 220,150 150,160" fill="#FF9800" transform="rotate(90 150 150)"/> <polygon points="150,140 220,150 150,160" fill="#009688" transform="rotate(135 150 150)"/> </svg> |
Important: If you only write rotate(45) → rotates around (0,0) → usually not what you want Always add the center point when rotating around something other than origin.
Example 3 – Scale + translate + rotate (real button hover effect)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<style> .btn:hover { transform: scale(1.15) translateY(-8px); } </style> <svg width="240" height="140" style="margin:40px;"> <g class="btn" transform="translate(40 40)"> <rect width="160" height="60" rx="12" fill="#2196F3"/> <text x="80" y="38" font-size="28" text-anchor="middle" fill="white"> Hover Me </text> </g> </svg> |
→ Hover → grows bigger and moves up slightly — very modern UI feel.
Example 4 – Skew (slant / fake perspective)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<svg width="400" height="200"> <rect x="40" y="40" width="120" height="120" fill="#4CAF50"/> <rect x="240" y="40" width="120" height="120" fill="#673AB7" transform="skewX(30)"/> <text x="100" y="180" font-size="28" text-anchor="middle">Normal</text> <text x="300" y="180" font-size="28" text-anchor="middle">Skewed</text> </svg> |
Quick Cheat Sheet – Transformation Order Tip
Remember: transform list is applied right-to-left
Want to:
- Scale first → then rotate → then move → Write: transform=”translate(…) rotate(…) scale(…)”
Common mistake:
|
0 1 2 3 4 5 6 |
transform="scale(2) translate(100 50)" ← first move, then scale → moves twice as far |
Correct for “scale then move”:
|
0 1 2 3 4 5 6 |
transform="translate(100 50) scale(2)" ← scale first → then move scaled distance |
Combining with CSS transform
In modern web development (2025–2026) you often see:
|
0 1 2 3 4 5 6 7 8 9 10 11 |
.icon { transition: transform 0.3s; } .icon:hover { transform: scale(1.2) rotate(15deg); } |
|
0 1 2 3 4 5 6 |
<svg class="icon">…</svg> |
→ CSS transform works perfectly on SVG elements (and overrides SVG transform attribute when both are present — CSS wins in conflict).
Common beginner mistakes
- rotate(45) without center → rotates around (0,0) → flies away
- Wrong order of functions → unexpected position/scale
- Forget units on translate/scale when mixing with CSS
- Apply transform to <g> but forget some children are outside → clip
- Too many transforms → hard to debug (group logically)
Mini practice for you
- Take a simple arrow (<polygon>) and rotate it 90°, 180°, 270° around its center
- Make a group of three circles, scale the whole group by 1.5 and move it down 50 units
- Create a “tilted” rectangle using skewX(20) and add a hover scale effect with CSS
Paste your code here if you want feedback — I’ll review it like we’re pair-programming together 😄
Transformations are one of the things that make SVG feel alive and interactive — once you master them, you can animate almost anything.
Next we can go into animation with transforms (SMIL or CSS), transform-origin in CSS, or matrix transforms if you want the math side.
Which part feels most confusing or exciting? Rotation centers? Order of transforms? Combining CSS + SVG? Just tell me — we’ll zoom in with more examples until it’s crystal clear and fun! 🚀
