Processing
 

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

15/08/2013 18:16#1

DaViS

Member

Joined at: 11 months ago

Post: 7

Thank: 0

Thanked: 0

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 im 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).

Any help is greatly appreciated. Thanx.

<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> 
16/08/2013 03:26Top#2

Phrogz

Member

Joined at: 11 months ago

Post: 43

Thank: 0

Thanked: 0

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)" /> 
01/05/2015 09:30Top#3

nikoloza

Member

Joined at: 11 months ago

Post: 3

Thank: 0

Thanked: 0

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.

01/04/2015 10:03Top#4

maechler

Member

Joined at: 8 months ago

Post: 1

Thank: 0

Thanked: 0

If you do not want want to modify / animate the svg there is a simpler solution than changing the url() parameter.

Include the svg as image:

<img src="/yourpath/image.svg"> 
03/11/2015 14:06Top#5

matehat

Member

Joined at: 8 months ago

Post: 1

Thank: 0

Thanked: 0

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.

17/06/2016 18:28Top#6

averydev

Member

Joined at: 8 months ago

Post: 1

Thank: 0

Thanked: 0

Ember 2.7 will replace the <base> tag with rootURL which should fix this issue.

In the meantime in my d3 for gradients I'm using the following:

.attr('fill', `url(${Ember.$(location).attr('href')}#my-gradient)`);

If you don't do this, the item you are targeting will seem to be transparent.

Similar articles

Chrome, THREE.js: Cross-origin image load denied

5 years ago - Reply: 5 - Views: 269

Prevent Google Chrome Log XMLHttpRequest

3 years ago - Reply: 5 - Views: 276

How can I include ChromeDriver in a JAR?

3 years ago - Reply: 3 - Views: 81

Chrome geolocation not working on any site

3 years ago - Reply: 1 - Views: 46

wrong borders' width in android browser

3 years ago - Reply: 4 - Views: 206

Uncaught SyntaxError: Unexpected token < On Chrome

3 years ago - Reply: 10 - Views: 468

Flashdata not getting cleared in Codeigniter

3 years ago - Reply: 5 - Views: 57

Illegal access Javascript error in Chrome

3 years ago - Reply: 1 - Views: 51

ng-repeat not updating in Chrome

3 years ago - Reply: 1 - Views: 81

Applying border to a checkbox in Chrome

4 years ago - Reply: 2 - Views: 118

open browser plugin using access vba

3 years ago - Reply: 1 - Views: 25

vé máy bay vé máy bay giá rẻ ve may bay ve may bay gia re vé máy bay vé máy bay giá rẻ ve may bay ve may bay gia re vé máy bay vé máy bay giá rẻ ve may bay ve may bay gia re vé máy bay vé máy bay giá rẻ ve may bay ve may bay gia re vé máy bay vé máy bay giá rẻ ve may bay ve may bay gia re vé máy bay vé máy bay giá rẻ ve may bay ve may bay gia re vé máy bay vé máy bay giá rẻ ve may bay ve may bay gia re