<href> in SVG

While creating an animated SVG logo for Indietech.rocks we ran into a strange problem where the SVG would display in some browsers and not in others. The issue is the different ways browsers handle XML — yes SVG is XML! So here is the problem and its solution.

<symbol> and <use> are very useful when creating SVGs. The <symbol>-tag defines a piece of SVG markup that can be reused repeatedly inside the SVG document. Whenever we want to use — that is, actually display — the defined symbol we simply link to it from a <use>-tag, just like we would use an <a>-tag to create hyperlinks.

As an example, let’s create an SVG with a symbol that defines a simple circle. Then we can use this circle elsewhere in the SVG by refering to the id attribute of the symbol using the href attribute of the <use>-tag.

<svg viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg" version="1.1">
  <symbol id="circ"><circle cx="100" cy="100" r="100"/></symbol>
  <use href="#circ"/>
</svg>

Now we can either use this SVG as an external source in <img> or embed it directly in the HTML page, as in the below figure.

SVG using href — external (left) and embedded (right)

Now, if you are using Safari you might not see any circles in the above image, but they both show up in Firefox, Chrome and Opera.


The problem is that the href attribute was defined in the 2.0 version of the SVG specification but not in the 1.1 version. I think Safari uses the older specification and so does not recognise the href attribute in <use>.

To fix this we have to use the xlink:href attribute instead.

<svg viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg" version="1.1">
  <symbol id="circ"><circle cx="100" cy="100" r="100"/></symbol>
  <use xlink:href="#circ"/>
</svg>
SVG using xlink:href — external (left) and embedded (right)

Now the embedded SVG is displayed in all browsers but the external one linked from an img does not display in Firefox, Chrome or Opera; so we fixed the issue for Safari but seemed to have messed it up for other browsers!


If you open the embedded image in Firefox it shows the error “XML Parsing Error: prefix not bound to a namespace”. It seems that browsers other than Safari do not understand the xlink-prefix to the href attribute. Blame this on the really excessive namespacing in XML.

The solution is to add an XML namespace for the xlink prefix. We can do this by adding xmlns:xlink="http://www.w3.org/1999/xlink" to the <svg> element.

<svg viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink">
  <symbol id="circ"><circle cx="100" cy="100" r="100"/></symbol>
  <use xlink:href="#circ"/>
</svg>
SVG using xlink:href with XML namespace for xlink — external (left) and embedded (right)

Now both images should display in all browsers… phew!

Send me (Learn more)

Replies

Mentions

Xavier Roy on xavierroy.com Kartik Prabhu on kartikprabhu.com Chris Aldrich

Reposts

Indie Tech Rocks! on Twitter