SVG coordinate systems explained for beginners
If you’re new to SVG, understanding coordinate systems is the key to predicting where elements appear on the canvas. In SVG, everything starts at a defined origin and follows a spe
SVG coordinate systems explained for beginners
If you’re new to SVG, understanding coordinate systems is the key to predicting where elements appear on the canvas. In SVG, everything starts at a defined origin and follows a specific direction for the x and y axes. This article breaks down the basics, with practical examples you can try in your projects. For deeper dives, you can explore more resources on SVG coordinate tips and related topics on SVGenus Design.
Where is the origin and how do axes move?
Unlike Cartesian graphs where the origin is usually in the center, SVG uses the top-left corner of the viewport as the origin (0, 0). The x-axis increases to the right, and the y-axis increases downward. This is often described as a “screen coordinate system.”
Practical takeaway: when you place an element at x="50" and y="20", it appears 50px to the right and 20px down from the top-left corner.
The viewBox and coordinate space
The viewBox attribute defines an internal coordinate system for the SVG canvas. It uses four numbers: min-x, min-y, width, height. A common pattern is viewBox="0 0 100 100", which sets a 100-by-100 unit space that you can map to any CSS size.
Tip: use viewBox to build scalable icons that adapt to different sizes without losing proportions.
Example snippet:
<svg width="200" height="200" viewBox="0 0 100 100" aria-label="Circle in viewBox">
<circle cx="50" cy="50" r="40" fill="tomato" />
</svg>
Notice how cx and cy refer to the internal 0–100 coordinate system, while the rendered size is 200 by 200 CSS pixels. For more on viewBox and responsive SVG, see this guide.
Inner coordinate systems: userSpaceOnUse vs. objectBoundingBox
When you apply gradients, patterns, or clip paths, SVG lets you define the coordinate system for those effects. Two common choices are userSpaceOnUse and objectBoundingBox.
- userSpaceOnUse: coordinates are in the SVG’s user coordinate system (the default viewBox). This is intuitive when you want effects to align with the overall canvas.
- objectBoundingBox: coordinates are normalized to the bounding box of the element (0 to 1). This is useful for scalable patterns that adapt to the element’s size.
Example: a linearGradient that aligns with the SVG canvas using userSpaceOnUse:
<defs>
<linearGradient id="grad" x1="0" y1="0" x2="100" y2="0" gradientUnits="userSpaceOnUse">
<stop offset="0%" stop-color="blue"/>
<stop offset="100%" stop-color="green"/>
</linearGradient>
</defs>
Using objectBoundingBox would switch to gradientUnits="objectBoundingBox" and adjust coordinates relative to the element’s size. Learn more about coordinate systems in gradients on SVG gradients for beginners.
Transforming coordinate spaces with groups
You can group elements with the <g>
element and apply transforms to shift or rotate the entire coordinate system for that group. This is a powerful way to position complex scenes without recomputing every single coordinate.
Example: translate moves the origin for all child elements of the group.
<svg width="200" height="100" viewBox="0 0 200 100" >
<g transform="translate(50, 25)">
<rect x="0" y="0" width="60" height="40" fill="skyblue"/>
<circle cx="30" cy="20" r="10" fill="orange"/>
</g>
</svg>
In this example, the group’s origin is shifted 50px right and 25px down, so the rectangle starts at (0,0) relative to the translated space, effectively appearing at (50,25) in the SVG canvas.
Practical examples: placing simple shapes with predictable coordinates
Try these quick demos to see how coordinates map to screen space. You can copy-paste into an HTML file to experiment.
Example 1: A small grid to visualize coordinates
<svg width="200" height="200" viewBox="0 0 100 100" >
<rect x="0" y="0" width="100" height="100" fill="none" stroke="#ccc"/>
<line x1="0" y1="0" x2="100" y2="0" stroke="red"/>
<line x1="0" y1="0" x2="0" y2="100" stroke="red"/>
</svg>
Example 2: A translated group with a dot at its origin
<svg width="240" height="120" viewBox="0 0 120 60" >
<g transform="translate(40, 10)">
<circle cx="0" cy="0" r="5" fill="purple"/>
</g>
</svg>
Common pitfalls and how to avoid them
Here are quick checks to keep SVG coordinates predictable:
- Always confirm the viewBox coordinates and the actual rendered size. A mismatch leads to stretching or misaligned elements.
- Remember that the origin is at the top-left. If you’re debugging layout, place temporary grid lines to visualize axes.
- When animating or transforming, keep a clear mental model of whether coordinates refer to the global canvas or a local group. Use transforms on
<g>
to simplify complex updates.