SVG Transformations

The transform attribute lets you move, rotate, resize, and slant any SVG element using translate, rotate, scale, and skew functions - either alone or chained together.

The transform Attribute

Every SVG shape and container element - <rect>, <circle>, <path>, <g>, and more - accepts a transform attribute. Its value is a space-separated list of one or more transform functions: translate(), rotate(), scale(), skewX(), and skewY(). Because transforms apply after the element is drawn in its local coordinate system, you can reposition or reshape a shape without touching its original x, y, width, or radius values.

translate(): Moving Along X and Y

translate(x, y) shifts an element by x units horizontally and y units vertically, relative to its current position. If you omit y, it defaults to 0, so translate(50) moves an element 50 units to the right only. Negative values move left or up.

Example

<!DOCTYPE html>
<html>
<body>

<svg viewBox="0 0 200 100">
  <rect x="10" y="10" width="40" height="40" fill="#3498db" />
  <rect x="10" y="10" width="40" height="40" fill="#e74c3c"
        transform="translate(80, 30)" />
</svg>

</body>
</html>

rotate(): Turning Around a Point

rotate(angle) spins an element clockwise by angle degrees around the SVG origin (0, 0) - which is rarely what you want, since it also moves the shape sideways. Pass a center point with rotate(angle, cx, cy) to rotate the element in place around that point instead, commonly the shape's own center.

Example

<!DOCTYPE html>
<html>
<body>

<svg viewBox="0 0 200 100">
  <rect x="70" y="20" width="60" height="30" fill="#2ecc71"
        transform="rotate(20, 100, 35)" />
  <circle cx="100" cy="35" r="2" fill="#000" />
</svg>

</body>
</html>

scale() and skew(): Resizing and Slanting

scale(sx, sy) multiplies every coordinate by sx horizontally and sy vertically; scale(2) alone scales both axes uniformly. skewX(angle) and skewY(angle) slant an element along one axis, useful for shadow or pseudo-3D panel effects. Multiple functions can be listed together in one transform attribute, and SVG applies them right to left, so transform="translate(100,0) rotate(45)" rotates first, then moves the rotated result.

Example

<!DOCTYPE html>
<html>
<body>

<svg viewBox="0 0 200 120">
  <rect x="0" y="0" width="40" height="40" fill="#9b59b6"
        transform="translate(20, 60) scale(1.5) skewX(-15)" />
</svg>

</body>
</html>
  • Order matters: transform functions are non-commutative, so translate then rotate gives a different result than rotate then translate.
  • rotate(), scale(), and skew() with no explicit center all pivot around the SVG coordinate origin (0, 0), not the shape's visual center.
  • Percentage values are not allowed inside the transform attribute (unlike CSS transform) - always use plain numbers.
  • Since SVG2, you can also set transforms via the CSS transform property and transform-origin, which does accept percentages and keywords like center.
  • Grouping shapes inside a <g transform="..."> applies one transform to every child at once, which is often cleaner than repeating it per shape.
Note: Add a small marker circle at the pivot point while you're building a rotation or skew - it makes the center of rotation obvious and speeds up debugging.
Note: transform="scale(-1, 1)" mirrors a shape horizontally, but it also flips it around the origin, which can push it off-screen. Combine it with a translate() to bring it back into view.
FunctionEffectExample
translate(x, y)Moves an element by x, ytranslate(40, 10)
rotate(a, cx, cy)Rotates a degrees around (cx, cy)rotate(45, 50, 50)
scale(sx, sy)Resizes by sx, sy factorscale(2, 0.5)
skewX(a)Slants along the x-axisskewX(20)
skewY(a)Slants along the y-axisskewY(-10)

Exercise: SVG Transformations

Why does the order of functions in transform='rotate(45) translate(50,0)' matter?