'How to reference external SVG file in SVG correctly?

Hello I am working on an SVG/JS map, which consists of many little SVG graphics (City districts). I put every graphic into an own file so that my main SVG file will still be maintainable and not bloated.

How can I reference an external SVG file from another SVG correctly?

Expected result: Open 1.svg in a browser and see a blue rectangle. How it should work: w3c: use element

So this is what I tried: 1.svg:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?xml-stylesheet href="style.css" type="text/css"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-       20010904/DTD/svg10.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"    width="1000" height="1000">
<use xlink:href="another.svg#rectangle"/>
</svg>

another.svg:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-       20010904/DTD/svg10.dtd">
<svg id="rectangle" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"    width="1000" height="1000">
<rect class="blue" x="558.5" y="570" width="5" height="5" />
</svg>

style.css

.blue { fill: blue; }

Result:

  • Firefox: A blue rectangle (exactly what I wanted)
  • Chrome: Nothing
  • Opera: Black rectangle

Note: I tried it with the image element but that didn't work with the stylesheets i.e. I got a black rectangle not a blue one.

Important: When you want to reference another SVG and want to have the referenced SVG to be part of the formal document structure, you can use AJAX to do that.

https://bugs.webkit.org/show_bug.cgi?id=12499



Solution 1:[1]

From the definition in the SVG spec that you linked to:

CSS2 selectors cannot be applied to the (conceptually) cloned DOM tree because its contents are not part of the formal document structure.

That means that your selector in 1.svg doesn't apply to the cloned DOM tree.

So why not simply reference the stylesheet from another.svg instead? That should work in all browsers, and with both <use> and <image>.

Another option is to style the <use> element in the main svg document (1.svg), since style is cascaded down to the cloned tree from there too.

Solution 2:[2]

Try to do it this way:

The square:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"    width="1000" height="1000">
    <rect x="558.5" y="570" width="5" height="5" id="rectangle" />
</svg>

Use it:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?xml-stylesheet href="style.css" type="text/css"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"    width="1000" height="1000">
    <use xlink:href="another.svg#rectangle" class="blue"/>
</svg>

Solution 3:[3]

<svg> element doesn't have xlink:href attribute, if you need to include an external image use the <image> element.

Solution 4:[4]

If you want to reference a whole SVG file, SVG 2 (when implemented in browsers) will allow to reference another SVG file without any fragment identifier:

New in SVG 2: An href without a fragment allows an entire SVG document to be referenced without having to ensure that it has an ID on its root element.

Before:

<!-- my-vector.svg -->

<svg id="icon" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
  <circle r="10" cx="12" cy="12" />
</svg>
<use href="my-vector.svg#icon"></use>

After (there will be no need to define id="..." on the svg):

<!-- my-vector.svg -->

<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
  <circle r="10" cx="12" cy="12" />
</svg>
<use href="my-vector.svg"></use>

SVG 2 seems to be in the process of development in major browsers (see this Chrome feature and specifically this Chromium issue: Issue 366545: [SVG2] Allow to reference entire files).

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Spadar Shut
Solution 3 Spadar Shut
Solution 4 Mahozad