Using base tag on a page that contains SVG marker elements fails to render marker
I've run into a problem while attempting to use SVG marker elements in an SVG based visualization. I'm adding my changes to a web application which happens to include a base tag on every page, so that any references to CSS files, javascript files, etc can be relative.
I have some example code below which reproduces the issue. There is a line element, and a marker element defined. The marker element is referenced by the line in its 'marker-end' attribute, via uri and id of marker. Without the base tag, the arrow displays fine. With the base tag, it is not shown. The reason is because the base tag changes the way the browser resolves urls.. even for the simple id based url specified in the marker-end attribute of the line.
Is there any way I can get around this problem without having to remove the base tag?
I can't really remove it because the use of it is fairly ingrained in the product I'm working on. I need to support Firefox, Chrome and IE9+ for my webapp. Firefox and chrome both produce this problem. IE works fine (ie. arrow marker displays).
<html>
<head>
<base href=".">
<style>
.link { stroke: #999; stroke-opacity: .6; }
marker#arrow { fill: black; }
</style>
</head>
<body>
<svg width="100%" height="100%">
<defs>
<marker id="arrow" viewBox="0 -5 10 10" refX="0" refY="0" markerWidth="20" markerHeight="20" orient="auto">
<path d="M0,-5L10,0L0,5"></path>
</marker>
</defs>
<line x1="100" y1="100" x2="333" y2="333" marker-start="url(#arrow)" class="link"></line>
</svg>
</body>
</html>
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.