Grouping with <g>
The <g> element is a container that groups child elements together. Groups have three main uses: they let you share presentation attributes (inherited by every child), apply a single transform to multiple shapes at once, and logically organize complex drawings so they are easier to reason about.
When you set fill, stroke, or opacity on a <g>, every descendant inherits those values — unless the child overrides them. This is the same CSS inheritance model you already know, applied to SVG presentation attributes.
Shared fill and stroke on a group
The circle and triangle inherit fill="#0f766e" from the group. The rectangle overrides it with its own fill="#d6452c". All three shapes share the stroke="#333" stroke-width="2" defined on the group — no need to repeat it on each element.
Transform functions
The transform attribute accepts one or more transform functions. SVG's transform functions mirror the CSS transform functions you may already know from web animation, but they use SVG user units (not CSS pixel values or deg keywords — just bare numbers for SVG transforms).
translate(tx ty)
Moves the shape's coordinate system by tx units right and ty units down. This is the most common transform — useful for repositioning a group without changing the coordinates of each child.
rotate(deg) and rotate(deg cx cy)
Rotates clockwise by the given number of degrees. The three-argument form rotate(deg cx cy) rotates around the point (cx, cy) in the current coordinate system, which is essential for rotating a shape about its own center. The two-argument form rotates around the SVG origin (0, 0), which usually sends the shape flying off-screen — see the rotation-origin section below for why.
scale(sx sy)
Scales the coordinate system. With one argument scale(s) the same factor applies to both axes; with two arguments scale(sx sy) you can stretch or compress independently. Like rotation without a center, scale by default expands outward from the origin — a common surprise for beginners.
skewX(deg) and skewY(deg)
Shears the coordinate system along the X or Y axis. skewX(deg) tilts vertical lines by deg degrees — turning a rectangle into a parallelogram. This is the SVG equivalent of the italic slant used in type design.
Combining transforms — order matters
When you write multiple transform functions in a single transform attribute, they are applied right to left — the last one listed executes first. This is the same convention as matrix multiplication. The result: "translate then rotate" places the shape differently than "rotate then translate".
A good mental model is that each transform function establishes a new local coordinate system. When you write transform="translate(60 0) rotate(40)", the rotate happens first in the original coordinate space, then the translate moves the already-rotated coordinate system 60 units to the right. Reverse them and you rotate a coordinate system that has already been shifted.
Side-by-side: same functions, opposite order
translate(60,0) rotate(40)rotate(40) translate(60,0)Both SVGs have the same ghost rectangle (gray) at the same origin and apply the same two functions — only the order differs. In the first case, the rectangle translates 60 units along the original horizontal axis, then rotates in place. In the second, the rectangle first rotates 40 degrees around the origin, which tilts its local X axis — so the subsequent translate moves it along the tilted axis, placing it in a completely different spot.
This is why transform order matters: each function modifies the coordinate system for all the functions to its left.
Rotation origin
rotate(deg) with a single argument rotates around the SVG origin — the top-left corner of the viewport. Most of the time this is not what you want. To spin a shape in place, you need to rotate around the shape's own center.
SVG provides two ways to do this:
rotate(deg cx cy)— the three-argument form rotates around the specific point (cx, cy) in the current coordinate system. This is the simplest approach when you know the center coordinates.- Translate–rotate–translate back — the general pattern:
translate(cx cy) rotate(deg) translate(-cx -cy). Equivalent to the three-argument form but works with other transform functions too (since you cannot specify a center forscale).
Rotate about shape center vs. SVG origin
rotate(35) — about SVG originrotate(35 80 70) — about own center
The gray ghost rectangle shows the original position in both cases. rotate(35) (left) swings the shape in a wide arc around (0, 0) — the top-left corner of the SVG. rotate(35 80 70) (right) spins it about (80, 70), which is the center of that rectangle (x + width/2 = 50 + 30 = 80; y + height/2 = 50 + 20 = 70), leaving it roughly in place but tilted.
If you are animating with CSS (transform-origin on the SVG element's CSS), be aware that CSS transforms on SVG elements use the CSS coordinate space, not the SVG user coordinate space. The SVG attribute transform always works in SVG user units, which is why the three-argument rotate form is more predictable for SVG-only work.