A pair of twin brothers sitting back-to-back

Cet article est également disponible en français

use is clone tool: it allows you to duplicate and replicate existing or predefined elements, while also providing the possibility of applying changes to the cloned copies. use is an easy way to lighten your SVG code using the best DRY ("Don’t Repeat Yourself") principles.

<use> case

Given an SVG element with an id:

<circle cx="50" cy="50" r="10" fill="red" id="primcirc" />

We can replicate the element with <use>:

<use xlink:href="#primcirc" />

The new copy will inherit every aspect of the original, and by default will be indistinguishable from it, meaning that we must add some change to the copy if it is to appear unique. However, this change can’t be anything declared in the original element. So this won’t work, as it clashes with the original:

<use xlink:href="#primcirc" fill="blue" />

The copy will appear red, not blue, as the fill was originally defined in the source element. However, adding a new attribute to the clone copy will work:

<use xlink:href="#primcirc" stroke="black" />

The copy will still have a red fill, but will now also ave a black stroke.

Using <defs>

To get around this problem, the “source” element is often placed inside a <defs> element. The source element includes attributes that won’t be changed in the clones:

<defs>
    <circle r="10" id="primcirc" />
</defs>

Anything that appears inside a <defs> element won’t be rendered in the SVG; defined elements will only appear via a reference. In this case, we add the attributes that were missing in the original definition to the clone:

<use xlink:href="#primcirc" cx="50" cy="50" fill="red" />

This creates the first visible instance of the circle. It will have a radius of 5, inherited from the original, but its own unique position and fill.

We can easily create another by copy adding a further <use> reference:

<use xlink:href="#primcirc" cx="80" cy="80" fill="yellow" />

Both circles will have a radius of 5, derived (and unchangeable) from the original definition, but each has its own position and fill.

If the original definition of the element included a position:

<defs>
    <circle r="10" cx="50" cy="50" id="primcirc" />
</defs>

Then we could alter the clone’s position using a transform:

<use xlink:href="#primcirc" fill="yellow" transform="translate(50 50)" />

Changes to the original definition will be reflected in the cloned copies.

It’s not only elements that can be cloned and referenced: you can also group elements together, provide the group with an id, and use it as many times as you wish:

<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 100 100">
<defs>
    <g id="primgroup">
        <circle cx="50" cy="50" r="10" fill="red" />
        <circle cx="70" cy="70" r="10" fill="blue" />
    </g>
</defs>
    <use xlink:href="#primgroup" />
</svg>

I’m using <circle> elements for the sake of simplicity, but source vectors could be almost anything. It’s also possible to generate <use> references with , as I’ll show in the next article.

Photograph by Melvin Pressouyre, used under a Creative Commons license

Enjoy this piece? I invite you to follow me at twitter.com/dudleystorey to learn more.