18

I am relatively new in SVG drawing with HTML5.

What I want to do is to make a group of elements in SVG with g element so that all elements inside of that g element can work like a group and all the element's base x and y value can be received from the upper g element.

So, what I have done is something like this-

<svg width="500" height="300" xmlns="http://www.w3.org/2000/svg">
  <g x="1000" y="1000">
    <title>SVG Title Demo example</title>
    <rect width="200" height="50"
    style="fill:wheat; stroke:blue; stroke-width:1px"/>
    <text style="text-anchor: middle;" class="small">My Text</text>
  </g>
</svg>

What I expected is all the elements inside the g element will get x="1000" and y="1000" so my expected output is like this-

enter image description here

But I am getting this-

enter image description here

Re-

I don't like to set x and y element in text element. I just want to set relative x and y into the text element if needed, but that should be relative to g element.

Can anyone help me what I need to do to achieve my target with a group in SVG?

Abrar Jahin
  • 13,970
  • 24
  • 112
  • 161

1 Answers1

29

<g> elements don't support x or y attributes. You can use a transform instead though.

I've decreased the values from 1000 to 100 as otherwise the output is outside the 500 x 300 canvas of the outer <svg> element.

I've provided additional x and y attributes on the text element so it appears positioned as in your example. If wanted you could put the text itself in a <g> element or an <svg> element.

<svg width="500" height="300" xmlns="http://www.w3.org/2000/svg">
  <g transform="translate(100, 100)">
    <title>SVG Title Demo example</title>
    <rect width="200" height="50"
    style="fill:wheat; stroke:blue; stroke-width:1px"/>
    <text x="100" y="30" style="text-anchor: middle;" class="small">My Text</text>
  </g>
</svg>

or using an additional <g> element to avoid x and y on the text itself.

<svg width="500" height="300" xmlns="http://www.w3.org/2000/svg">
  <g transform="translate(100, 100)">
    <title>SVG Title Demo example</title>
    <rect width="200" height="50"
    style="fill:wheat; stroke:blue; stroke-width:1px"/>
    <g transform="translate(100, 30)">
        <text style="text-anchor: middle;" class="small">My Text</text>
    </g>
  </g>
</svg>

Alternatively you could use an inner <svg> element instead of a <g> element as that does support x and y attributes

<svg width="500" height="300" xmlns="http://www.w3.org/2000/svg">
  <svg x="100" y="100">
    <title>SVG Title Demo example</title>
    <rect width="200" height="50"
    style="fill:wheat; stroke:blue; stroke-width:1px"/>
    <text x="100" y="30" style="text-anchor: middle;" class="small">My Text</text>
  </svg>
</svg>
Robert Longson
  • 118,664
  • 26
  • 252
  • 242
  • Could you add some relative merits and considerations for each of these? When is it appropriate to nest svgs? Are there performance drawbacks? What about using transform versus native x and y attributes? – Alex Lenail Jul 28 '18 at 13:12
  • I'd use none of them, instead I'd set x and y attributes on the text element. The OP for some unfathomable reason doesn't want to do things the easy way. Performance varies with browsers and platforms and graphics cards. – Robert Longson Jul 28 '18 at 13:23
  • I have a fairly complicated setup where I have a nested selection. Imagine a table with rows and cells inside rows. Sometimes I want to re-order the rows, and I want to change the y coordinate on the row element. I had the row as a `` but now its an `` and the behavior works, but it isn't pretty. Given my data structure, it would be really tricky to update the y coordinates on each of the elements separately, and would be nice if I could do it on the row... – Alex Lenail Jul 28 '18 at 13:28
  • You should probably as a separate question although you'd have to define clearly what "not pretty" means. Maybe one of my answers is for you, try them and see. – Robert Longson Jul 28 '18 at 13:31
  • 1
    @AlexLenail I am inclined to suggest that using nested `` elements is more in the spirit of SVG: you’re effectively nesting images, and you’re creating a structure similar to what OP wants to do with the `` elements. As regards doing things the easy way, I personally think applying absolute positioning attributes individually is not doing things the easy way. – Manngo Jul 30 '21 at 06:52