Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why the <use> tag in SVG doesn't work?

Tags:

html

css

svg

I have the following simple example. It is stored in image.svg:

<svg>
  <defs>
    <g id="shape">
      <circle cx="100" cy="100" r="100" />
    </g>
  </defs>
</svg>

However, putting this code in a HTML file doesn't load anything. Why is that?

<svg>
  <use xlink:href="#shape" x="10" y="10" />
</svg>

What am I doing wrong? I can't seem to make it work.

like image 206
BarbuDorel Avatar asked Dec 06 '22 15:12

BarbuDorel


2 Answers

If you are using elements from another document, you have to specify the document!

<use xlink:href="#shape" x="10" y="10" />

This means "use the #shape element from the current document".

To import from another document, you need to put the reference to the SVG file in the xlink:href attribute:

<use xlink:href="image.svg#shape" x="10" y="10" />

Obviously you need to check the path is correct here. Note that this is not supported in any version of Internet Explorer, though polyfills are available.

like image 166
lonesomeday Avatar answered Dec 21 '22 05:12

lonesomeday


For external svg files you need the namespace ... and I have added a fill to render the circle otherwise it will be transparent:

<svg xmlns="http://www.w3.org/2000/svg" >
  <symbol id="shape" width="200" height="200" viewbox="0 0 200 200">
    <circle cx="100" cy="100" r="100" fill="currentColor" />
  </symbol>
  <text y="20">Symbol above will not render unless referenced by use element</text>
</svg>

Then when you reference it you need to use the correct namespace for xlink:

svg.defs-only {
  display:block; position: absolute; 
  height:0; width:0; margin: 0; padding: 0; 
  border: none; overflow: hidden;
}

svg {
  color: orange;
  stroke: red;
}

.purple {
  color: purple;
  stroke: black;
}
<svg class="defs-only" xmlns="http://www.w3.org/2000/svg" >
  <symbol id="shape" width="50" height="50" viewbox="0 0 50 50">
    <circle cx="25" cy="25" r="20" fill="currentColor" stroke="inherit" />
  </symbol>
</svg>

<svg xmlns:xlink="http://www.w3.org/1999/xlink">
   <use xlink:href="#shape" x="10" y="10" />
   <use xlink:href="#shape" x="80" y="10" class="purple" />
</svg>

If you are referencing an external file, you need to put the filename before the # e.g. image.svg#shape making sure you get the path correct of course.

Note, not all browsers support fragment identifiers - notably IE and Edge - you need to use a javascript polyfill like svg4everybody for those browsers.

Workaround - use svg inline only

like image 42
Ruskin Avatar answered Dec 21 '22 05:12

Ruskin