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

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)" />

SVG markers not appearing in Edge and Firefox (D3.js, Angular2)

Problem solved. Angular2 uses

<base href="/">

on the page, which fouls the path's ability to find url(#Arrow).

The solution is to add the marker attribute in d3.js and pre-pend the location.href:

renderArrows() {
var arrows = d3.selectAll('path.arrow');

arrows.each(function (d) {
var path = d3.select(this);
path
.attr('stroke-linecap', 'round')
.attr('marker-end', function(d,i){ return "url(" + location.href + "#Arrow)" })
})
}

More information here:
Using base tag on a page that contains SVG marker elements fails to render marker

base tag breaks SVG marker-end rendering

You can fully resolve the marker url.

If it is an arbitrary document which is using a base tag, then you can use document.URL. For example, "url(" + document.URL + "#end" + ")" in place of url(#end) (line 167 of your example JSBin).

For angular in particular, there are two possible solutions.

First, if you are the marker-reference on the client (for example, using d3), then you need to fully resolve the URL yourself as above.

Second, if you are using server-side generated SVG you can use the angular scope.

$scope.baseUrl = $location.absUrl();

When you create the SVG, refer to the property.

<svg>
<defs>
<marker id="end">...</marker>
</defs>
<line marker-end="url({{baseUrl}}#end)" .../>
</svg>

SVG Marker does not work

There are three reason causing marker to not work:

  1. You haven't specified a stroke colour for your path, so it won't show up (and neither will the markers).

  2. You have specified marker-mid markers when the path doesn't have any midpoints. It's just a single line segment. Try d="M0,0L100,100,200,200" to add a mid point.

  3. Finally your markerWidth and markerHeight are too small (3x3) for the circle which is centred at (6,6) and radius 5. Try markerWidth="12" markerHeight="12".

http://jsfiddle.net/fP5EY/

SVG markers broken in internet explorer?

Add the stroke: none; in tour path style. Like this:

<svg viewBox="0 0 100 100">
<defs>
<marker id="arrow" markerWidth="5" markerHeight="6" refx="5" refy="2" orient="auto">
<path d="M0,0 L0,4 L5,2.5 L5,1.5 L0,0" style="fill:red; stroke: none;" ></path>
</marker>
</defs>

<path d="M0,0 L50,50"
style="stroke:red; stroke-width: 10px; fill: none;
marker-end: url(#arrow);"
></path>
</svg>

It's working in IE-11.

how to customize the marker drop with another svg?

You have to use the markerPathFunction property with your custom SVG path. (There is no such property like markerFunction and markerPath.)

window.onload = function () {
var wheel = new wheelnav("wheelDiv");
wheel.markerPathFunction = CustomMarker;
wheel.createWheel();
};

var CustomMarker = function (helper, percent, custom) {
return {
markerPathString: "m436 413.2c-4.9-2.8-6.7-6.6-5.8-12 0-0.5 0-1-0.1-1.4-0.7-21.9-1.5-43.9-2.2-66.2l26.8 1.6c-3.6-7.4-6.8-14.4-10.5-21.2-6.3-11.5-10.8-23.5-12.5-36.6-1.6-12.1-3.3-24.1-5-36.2l-2.1-0.3c-0.4 2.2-1.1 4.3-1.2 6.5-0.1 4.3 0.5 8.7 0 13-2.7 24.1-5.3 48.2-24.6 66.1-1.5 1.4-2.5 3.2-4 5.1l26.2 1.6-0.9 76.1c-8.6 3-10.5 10-9.4 18.7 0.9 7 5.6 10 11.5 12.1 0.6 0.2 1.1 0.5 1.6 0.8 4.1-0.1 8-0.7 11.5-2.2 0.5-0.4 1-0.8 1.4-1.1 0.1 0 0.2-0.1 0.2-0.1 0.4-0.8 0.9-1.7 1.4-2.4l0.3-0.3c0.8-3 1.2-6.2 1.8-9.3 1.2-4.9 0.1-9.7-4.4-12.3zm-19.9 15.5c-3.4-3.5-2.5-6.8 0.6-10.2-0.2 3.2-0.4 6.5-0.6 10.2zm3.4-5.6c-0.3-0.4 2.9-2.9 3.9-4 4.7 0.5 7.3 2.4 6.7 5.9-0.3 1.9-2.9 3.5-4.4 5.2-2.1-2.2-4.5-4.4-6.2-7.1zm4.8 12.1c3.8-2.9 7.8-5.8 12.5-9.3-1.4 8.9-6.2 11.9-12.5 9.3z"
};
};

In your case (it works with HTML tags), you have to use the data-wheelnav-init attribute also.

What are the recommendations for html base tag?

Breakdown of the effects of the base tag:

The base tag appears to have some non-intuitive effects, and I recommend being aware of the outcomes and testing them for yourself before relying on <base>! Since I've discovered them after trying to use the base tag to handle local sites with differing urls and only found out the problematic effects after, to my dismay, I feel compelled to create this summary of these potential pitfalls for others.

I'll use a base tag of: <base href="http://www.example.com/other-subdirectory/"> as my example in the cases below, and will pretend that the page that the code is on is http://localsite.com/original-subdirectory

Major:

No links or named anchors or blank hrefs will point to the original subdirectory, unless that is made explicit:
The base tag makes everything link differently, including same-page anchor links to the base tag's url instead, e.g:

  • <a href='#top-of-page' title='Some title'>A link to the top of the page via a named anchor</a>

    becomes

    <a href='http://www.example.com/other-subdirectory/#top-of-page' title='Some title'>A link to an #named-anchor on the completely different base page</a>

  • <a href='?update=1' title='Some title'>A link to this page</a>

    becomes

    <a href='http://www.example.com/other-subdirectory/?update=1' title='Some title'>A link to the base tag's page instead</a>

With some work, you can fix these problems on links that you have control over, by explicitly specifying that these links link to the page that they are on, but when you add third-party libraries to the mix that rely on the standard behavior, it can easily cause a big mess.

Minor:

IE6 fix that requires conditional comments: Requires conditional comments for ie6 to avoid screwing up the dom hierarchy, i.e. <base href="http://www.example.com/"><!--[if lte IE 6]></base><![endif]--> as BalusC mentions in his answer above.

So overall, the major problem makes use tricky unless you have full editing control over every link, and as I originally feared, that makes it more trouble than it's worth. Now I have to go off and rewrite all my uses of it! :p

Related links of testing for issues when using "fragments"/hashes:

http://www.w3.org/People/mimasa/test/base/

http://www.w3.org/People/mimasa/test/base/results


Edit by Izzy: For all of you running into the same confusion as me concerning the comments:

I've just tested it out myself, with the following results:

  • trailing slash or not, makes no difference to the examples given here (#anchor and ?query would simply be appended to the specified <BASE>).
  • It however makes a difference for relative links: omitting the trailing slash, other.html and dir/other.html would start at the DOCUMENT_ROOT with the given example, /other-subdirectory being (correctly) treated as file and thus omitted.

So for relative links, BASE works fine with the moved page – while anchors and ?queries would need the file name be specified explicitly (with BASE having a trailing slash, or the last element not corresponding to the name of the file it's used in).

Think of it as <BASE> replacing the full URL to the file itself (and not the directory it resides in), and you'll get things right. Assuming the file used in this example was other-subdirectory/test.html (after it moved to the new location), the correct specification should have been:

<base href="http://www.example.com/other-subdirectory/test.html">

– et voila, everything works as expected: #anchor, ?query, other.html, very/other.html, /completely/other.html.



Related Topics



Leave a reply



Submit