Why nest an <svg> element inside another <svg> element?

Nesting SVG elements can be useful to group SVG shapes together, and position them as a collection. All shapes nested inside an svg element will be positioned (x, y) relative to the position (x, y) of its enclosing svg element. By moving the x and y coordinates of the enclosing svg element, you move all the nested shapes too.

Here is an example where two rectangles are nested inside two svg elements. Except for the colors the two rectangles have the same definitions for x, y, height, and width. The enclosing svg elements have different x-values. Since the x-position of the rectangles are interpreted relative to their enclosing svg elements x-position, the two rectangles are displayed at different x-positions.

- By Jakob Jenkov

<svg xmlns="http://www.w3.org/2000/svg"
  xmlns:xlink="http://www.w3.org/1999/xlink">
  <svg x="10">
    <rect x="10" y="10" height="100" width="100"
        style="stroke:#ff0000; fill: #0000ff"/>
  </svg>
  <svg x="200">
    <rect x="10" y="10" height="100" width="100"
        style="stroke:#009900; fill: #00cc00"/>
  </svg>
</svg>

Credits


You can define a new viewport & viewbox. With this option, you can use relative positions like as css. For more information, you can see this online article.

<!DOCTYPE html>
<html lang="en">

<head>
    <title>Nested SVG</title>
    <style>
        html,
        body {
            margin: 0;
            padding: 0;
            width: 100%;
            height: 100%;
            overflow: hidden;
        }
    </style>
</head>

<body>
    <svg width="100%" height="100%">
        <rect x="25%" y="25%" width="50%" height="50%" style="fill: dodgerblue;" />
        <svg x="25%" y="25%" width="50%" height="50%">
            <rect x="25%" y="25%" width="50%" height="50%" style="fill: tomato;" />
        </svg>
    </svg>
</body>

</html>

You're right (as you say in Mr. Alien's answer) that both SVG elements have the same relative positions, and indeed the graph displays fine without the outer SVG.

The reason I added it is because the JavaScript (which I needed to stop the labels getting squished) uses the SVG element's transform matrix (caused by the applied viewBox attribute) to unscale the text.

Unfortunately the returned matrix doesn't take account of transformations applied to the SVG element itself, so I needed to get the transform matrix relative to an outer element that used the initial coordinate system instead. Hope that helps.

Tags:

Svg