SVG g element
Jakob Jenkov |
The SVG <g>
element is used to group SVG shapes together. Once
grouped you can transform the whole group of shapes as if it was a single shape.
This is an advantage compared to a nested <svg>
element
which cannot be the target of transformation by itself.
You can also style the grouped elements, and reuse them as if they were a single element.
SVG g Example
Here is a simple SVG g
example:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <g> <line x1="10" y1="10" x2="85" y2="10" style="stroke: #006600;"/> <rect x="10" y="20" height="50" width="75" style="stroke: #006600; fill: #006600"/> <text x="10" y="90" style="stroke: #660000; fill: #660000"> Text grouped with shapes</text> </g> </svg>
Here is the resulting image:
This example shows 3 shapes grouped together in a <g>
-element. As it is listed here, there is no particular
benefit in this grouping. But watch what happens when we request the <g>
-element transformed.
Here is the code:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <g transform="rotate(45 50 50)"> <line x1="10" y1="10" x2="85" y2="10" style="stroke: #006600;"/> <rect x="10" y="20" height="50" width="75" style="stroke: #006600; fill: #006600"/> <text x="10" y="90" style="stroke: #660000; fill: #660000"> Text grouped with shapes</text> </g> </svg>
And here is the resulting image:
Notice how all shapes within the <g>
-element are rotated 45 degrees around the point 50,50.
The Styling of g Elements are Inherited by Its Children
The CSS styles of a <g>
element are inherited by its child elements. Here is an example:
<g style="stroke: #0000ff; stroke-width: 4px; fill: #ff0000"> <rect x="10" y="10" width="100" height="50" /> <circle cx="150" cy="35" r="25" /> <circle cx="250" cy="35" r="25" style="stroke: #009900; fill: #00ff00;"/> </g>
This example defines a <g>
element with three child elements. The <g>
element has a style
attribute. The two first child elements do not have a style
attribute.
Therefore the styles defined in the <g>
element are inherited by these child elements.
The third child element has a style
attribute which sets the stroke and fill color, but it
still inherits the stroke-width
of the <g>
element.
Here is the resulting image:
Drawback: G Elements Have no X and Y Attributes
The ability to transform all shapes within a <g>
-element is an advantage compared to grouping
shapes within a nested <svg>
-element. <svg>
-elements cannot be transformed by themselves.
You will have to nest the <svg>
-element within a <g>
-element to transform its nested shapes.
The <g>
-element has one disadvantage compared to the <svg>
-element, though. You cannot
move the <g>
-element including all nested shapes around, just by changing the <g>
-element's
x and y attributes. The <g>
-element doesn't have x and y attributes. To move the contents of
a <g>
-element you can only do so using the transform
attribute, using the
"translate" function, like this: transform="translate(x,y)"
.
If you need to move all shapes within a <g>
-element using x and y attributes you will need to
nest the <g>
-element inside an <svg>
-element. The <svg>
-element has x and y attributes.
Here is an example:
<svg x="100" <g transform="rotate(45 50 50)"> <line x1="10" y1="10" x2="85" y2="10" style="stroke: #006600;"/> <rect x="10" y="20" height="50" width="75" style="stroke: #006600; fill: #006600"/> <text x="10" y="90" style="stroke: #660000; fill: #660000"> Text grouped with shapes</text> </g> </svg>
In this example all shapes within the <g>
-element are nested inside an
<svg>
-element. Notice that the <svg>
has its x-attribute set
to 100. That means that first the shapes within the <g>
are transformed,
then moved 100 along the x-axis, because the <svg>
is positioned at x=100.
Here is the resulting image:
You can also switch the nesting, and nest the <svg>
-element inside the
<g>
-element, like this:
<g transform="rotate(45 50 50)"> <svg x="100" <line x1="10" y1="10" x2="85" y2="10" style="stroke: #006600;"/> <rect x="10" y="20" height="50" width="75" style="stroke: #006600; fill: #006600"/> <text x="10" y="90" style="stroke: #660000; fill: #660000"> Text grouped with shapes</text> </svg> </g>
Then the shapes are first moved 100 along the x-axis because the <svg>
-element is
positioned at x="100", and then rotated from that location 45 degrees around the point 50, 50.
Here is the resulting image:
The two images may look similar, but there is a difference. The difference consists of the order the movement and rotation are carried out. You can also see that on the images, if you look closely. The shapes displayed are not positioned equally. In addition, notice how the first image has the text cut off at the beginning, even if the text is displayed at good bit into the image in the x-direction. This happens because the shapes are first rotated, and in the rotation part of the text sticks out of the image. When moved to the left afterwards, the missing text-part is still missing.
Tweet | |
Jakob Jenkov |