With JavaScript, can I change the Z index/layer of an SVG <g> element?

Let's say I have a couple composite shapes (<g>). I want to be able to click and drag them, but I want the one I happen to be dragging at the moment to be on TOP of the other one in the Z order, so that if I drag it over the OTHER one, the other one should be eclipsed.


Solution 1:

Z index in SVG is defined by the order the elements appear in the document. You will have to change the element order if you want to bring a specific shape to the top.

Solution 2:

An alternative to moving elements in the tree is to use <use> elements where you change the xlink:href attribute so that it gives you the z ordering you want.

Here's an old thread on svg-developers mailinglist discussing this topic in context of wanting to animate some shapes.

Update:

<svg xmlns="http://www.w3.org/2000/svg" 
     xmlns:xlink="http://www.w3.org/1999/xlink"
     style="width:100%; height: 100%">
    <circle id="c1" cx="50" cy="50" r="40" fill="lime" />
    <rect id="r1" x="4" y="20" width="200" height="50" fill="cyan" />
    <circle id="c2" cx="70" cy="70" r="50" fill="fuchsia" />
    <use id="use" xlink:href="#c1" />
</svg>

In this example the <use> element is the last one, which makes it the frontmost element. We can choose any of the other elements to act as frontmost simply by changing the xlink:href attribute. In the above example we picked the circle with id="c1", which makes it appear as the topmost element.

See fiddle.

Solution 3:

This is old question, but...

On FireFox (7+) and Chrome (14+) you can pull svg_element to the top. This does not give you freedom of full z axis control, but it's better than nothing ;)

Just append that element again.

var svg = doc.createElemNS('svg');
var circle = doc.createElemNS('circle');
var line = doc.createElemNS('line');

svg.appendChild(circle); // appends it
svg.appendChild(line);   // appends it over circle
svg.appendChild(circle); // redraws it over line now

I thought it was going to throw en error or something.

appendChild == replace itself == redraw