Using base tag on a page that contains SVG marker elements fails to render marker Using base tag on a page that contains SVG marker elements fails to render marker google-chrome google-chrome

Using base tag on a page that contains SVG marker elements fails to render marker


The HTML <base> element is used to say "resolve all relative URLs relative not to this page, but to a new location". In your case, you've told it to resolve relative to the directory with the HTML page.

The SVG marker-mid="url(…)" attribute is a FuncIRI Reference. When you use a value like url(#foo) that relative IRI is normally resolved relative to the current page, finding the element with the foo id. But, when you use <base>, you change where it looks.

To solve this problem, use a better value. Since your base reference is the current directory, you can simply use the name of the current file:

<line … marker-mid="url(this_page_name.html#arrow)" />

If you have a different <base> href, than what you've shown, like:

<base href="http://other.site.com/whee/" />

then you will need to use an absolute href, e.g.

<line … marker-mid="url(http://my.site.com/this_page_name.html#arrow)" />


Try with javascript:

<line id="something" />

With native:

document.getElementById('something').setAttribute('marker-mid', 'url(' + location.href + '#arrow)');

With jQuery:

$('#something').attr('marker-mid', 'url(' + location.href + '#arrow)');

It just works.


In the context of a rich web app like one built on Angular, where you need to set the <base> tag to make HTML5-style navigation work, it can get messy to try to fix that in a permanent way.

In my case, the app I was working on was showing a SVG-based interactive diagram builder that would change the app url as I selected elements therein.

What I did was to add a global event handler that would fix all url(#...) inline styles in any <path> element found in the page:

$rootScope.$on 'fixSVGReference', ->    $('path').each ->        $path = $ this        if (style = $path.attr 'style')?            $path.attr 'style', style.replace /url\([^)#]*#/g, "url(#{location.href}\#"

Then trigger this handler in key places, like when the app state changes (I'm using ui-router)

$rootScope.$on '$stateChangeSuccess', ->    $timeout (-> $rootScope.$emit 'fixSVGReference'), 5

As well as anywhere where I know there'd be new/updated paths like these. Here, the $timeout thing is to account for the fact that the DOM nodes really are changed asynchronously sometime after the $stateChangeSuccess event is triggered.