SVG g, defs, symbol and use: group and reuse shapes
In SVG, g groups shapes so they can be styled and moved together, defs and symbol hold shapes for later, and use draws a copy. Code, sprites and faults.
Published
The <g> element is SVG’s group: a container whose attributes, such as fill, opacity and transform, act on everything inside it. <use> draws a copy of a shape or group that is defined somewhere else. <defs> and <symbol> hold things that are defined without being drawn, ready for <use>. Together they keep a file short and make one change apply everywhere.
g: the group
A complete file with one group:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 60">
<g fill="none" stroke="navy" stroke-width="4" transform="translate(10 10)">
<circle cx="20" cy="20" r="15"/>
<rect x="45" y="5" width="30" height="30"/>
</g>
</svg>
Both shapes are outlined in navy and both are moved 10 units right and 10 down, though neither carries a style of its own. That is the whole purpose of a group: say something once.
What a group does:
- Passes styles down.
fill,stroke,font-sizeand other inherited properties set on the<g>apply to every child that does not set its own. - Moves its contents as one. A
transformon the group moves, turns or scales everything in it. SVG transform explains the values. - Fades as one.
opacity="0.5"on a group fades the finished group, so shapes that overlap inside it do not show through each other. The same opacity on each shape would. - Gives a name to a part. An
idorclasson the group lets CSS, JavaScript or a<use>refer to all of it.
A group has no position or size of its own. x, y, width and height do nothing on a <g>: to place it, use transform="translate(x y)". Groups can sit inside groups to any depth.
Vector editors use groups for structure. Inkscape, for one, saves each of its layers as a <g> with a label, which is why a layered design opened as code is a list of groups.
defs: define now, draw later
Anything inside <defs> is not drawn where it is written. It waits to be referred to by its id. Gradients, clipping paths, masks and filters are kept there by convention, along with shapes meant for <use>.
use: draw a copy
Another complete file:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 120 40">
<defs>
<polygon id="tri" points="0,30 15,0 30,30"/>
</defs>
<use href="#tri" x="5" y="5" fill="teal"/>
<use href="#tri" x="45" y="5" fill="gold"/>
<use href="#tri" x="85" y="5" fill="tomato"/>
</svg>
One triangle is defined and drawn three times, in three colours. href names the original by its id. x and y shift the copy: they are added to wherever the original was drawn, so define the original at 0,0. A <use> can also take a transform.
The copies are live. Change the points of the original and all three change.
Colour. The copy takes inherited properties from its <use>, which is how each triangle above gets a different fill. That only works because the polygon sets no fill itself. A fill attribute on the original cannot be overridden from the <use>.
CSS. A selector cannot reach into a copy through the <use>: use polygon { ... } matches nothing. Rules that match the original apply to every copy.
href or xlink:href. Older files write xlink:href="#tri", with xmlns:xlink="http://www.w3.org/1999/xlink" declared on the root element. Current browsers read both forms. Some other software reads only the older one.
symbol: a reusable drawing with its own viewBox
A <symbol> is a group that is never drawn where it stands, only through <use>, and that can carry its own viewBox. The viewBox is what makes it useful for icons: the copy scales to fit whatever box it is given.
<g> inside <defs> | <symbol> | |
|---|---|---|
| Drawn in place | No, because of the <defs> | Never |
| Own viewBox | No | Yes |
| Size of a copy | The size it was drawn at | Fits the width and height of the <use>, or of the SVG around it |
SVG sprites
A sprite is one SVG holding many symbols, each with an id. This example is for pasting into an HTML page:
<svg width="0" height="0" style="position: absolute" aria-hidden="true">
<symbol id="icon-play" viewBox="0 0 24 24">
<path d="M8 5v14l11-7z"/>
</symbol>
<symbol id="icon-stop" viewBox="0 0 24 24">
<rect x="6" y="6" width="12" height="12"/>
</symbol>
</svg>
<svg width="24" height="24" fill="currentColor"><use href="#icon-play"/></svg>
<svg width="48" height="48" fill="currentColor"><use href="#icon-stop"/></svg>
The first SVG draws nothing and takes no room. Each later one shows a single icon at the size set on it, in the colour of the surrounding text.
The sprite can also be a file of its own, referred to with the file’s address before the #:
<svg width="24" height="24"><use href="/icons.svg#icon-play"/></svg>
The browser fetches the file once and takes every icon from it. Two conditions apply. The file must come from the same origin as the page: the same scheme, host and port. And as a standalone file, icons.svg needs xmlns="http://www.w3.org/2000/svg" on its root element. SVG in HTML compares sprites with the other ways of placing an SVG.
Use and cutting machines
Browsers and vector editors follow a <use> reference. Cutting, laser and plotter software varies, and a program that does not follow it will leave the copies out. Before sending a file to a machine, turn copies into real shapes. In Inkscape a <use> is called a clone, and Edit, Clone, Unlink Clone makes a selected clone an independent object.
Groups are widely understood. A cutting program may show a group as one item until it is ungrouped, as described in uploading an SVG to Cricut Design Space.
Common problems
| What you see | Cause | Fix |
|---|---|---|
<use> draws nothing | The id after # matches no element, or the sprite file is on another origin | Match the id exactly, capitals included. Serve the file from the page’s own origin |
The copy ignores fill on the <use> | The original sets its own fill | Remove the fill from the original, or set it to currentColor and set color on the <use> |
| The copy is in the wrong place | x and y add to the original’s own position | Draw the original at 0,0 |
| An icon is the wrong size or cropped | The symbol has no viewBox | Add one that fits the artwork: see SVG viewBox explained |
| A CSS rule does not reach the copy | Selectors do not pass through <use> | Style the original, or set inherited properties on the <use> |
x or width on a <g> does nothing | A group has no geometry of its own | Use transform |
| Copies are missing in another program | It does not support <use>, or reads only xlink:href | Unlink the clones before saving |
Questions
What is the difference between g and svg as containers? A nested <svg> sets up a new viewport with its own x, y, width, height and viewBox, and clips to it by default. A <g> does none of that: it only groups.
Does a group affect file size? Slightly, for the better: one style on a group replaces the same style repeated on every shape.
Can a <use> copy something from another SVG on the same page? Yes. Ids are shared across the whole HTML page, which is also why two inline SVGs must not define the same id.
How can the groups in a file be seen? Open it in the SVG viewer. It counts the groups, paths and other elements and shows the code.