Inline SVG + HTML tag broken paths

I’m working with SVG lately, in particular with music notation.

In particular, I have an SVG image loaded inline the html page directly in the code (without using an <img> tag).

Until yesterday (15 Mar 2016), the SVG displayed fine in Chrome (version 48):

Correct SVG

Starting from the day after, here’s what I started to see:

Before svg base fix

This has been very hard to debug, because during those two days I didn’t change anything in the code. After some debugging I found what was causing the problem: the <base> tag, and the fact that the browser automatically updated to version 49. Probably Chrome developers changed something that is related to this behavior.

So, how could we sold this problem?

Solution 1

Remove the <base> tag.

Solution 2

Don’t use inline svg, use an <img> tag. E.g.: <img src="myImage.svg">

Notice that this could create some issues if you’re manipulating SVG elements directly (e.g. with jQuery), because the SVG elements won’t be part of your DOM anymore.

Solution 3

Use a javascript fix. Without jQuery:

var baseUrl = window.location.href.replace(window.location.hash, "");
[].slice.call(document.querySelectorAll("use[*|href]"))
  .filter(function(element) {
    return (element.getAttribute("xlink:href").indexOf("#") === 0);
  })
  .forEach(function(element) {
    element.setAttribute("xlink:href", baseUrl + element.getAttribute("xlink:href"));
  });

With jQuery:

if ($("base").length) {
        var Url = window.location.href;
        var hash = window.location.hash;
        var CleanUrl = Url.replace(hash, "");
        var origin = window.location.origin.length + 1;
        var trimmedUrl = CleanUrl.substring(CleanUrl.length, origin);
        $("svg:not(.no-convert) use").each(function(){
            var href = $(this).attr("xlink:href");
            var str = href.split("?");
            str = str[str.length - 1];
            $(this).attr("xlink:href", trimmedUrl  + str);
        });
    }

Both solutions work, but remember to include this code in a callback you can bind to an event (e.g. document loaded, SVG loaded after an ajax call, etc..), or it won’t work as you may expect.

Sources:

Also read...

Leave a Reply

Your email address will not be published. Required fields are marked *