Rendering Order
From Svg wiki
Changing Drawing Order
Also known as Z-Index or Layering
Often in interactive or dynamic SVGs, you may wish to move an element to the front or rear of another element. Currently, there is no explicit way of doing this in SVG; to do so, you must manipulate the DOM.
SVG elements are rendered via the painter's algorithm, i.e. subsequent elements are painted on top of previously painted elements. Essentially, the placement of your nodes (elements) in the file is what determines the "z" value. Therefore:
<rect ... > <line ... >
will put the <line> "on top of" the <rect>,
whereas reversing it:
<line ... > <rect ... >
will put the <rect> node on top of the <line> node, thereby obscuring the view of the line:
There are perennial discussions about the introduction of a z-index attribute which would control explicitly the layered placement of elements. There is a chance that this attribute will be introduced in a later version of SVG (see SVG Wishlist).
In the meantime, the only way to change the drawing order is to change the element's position in the DOM.
The following implementation uses the method =replaceChild= on the DOM's Node object:
function zSwap(parent, elem1, elem2)
{
var tmp = elem1.cloneNode( true );
parent.replaceChild( tmp, elem2 );
parent.replaceChild( elem2, elem1 );
}
This solution requires that both elements are children of the same parent. Also note that any assigned event listeners will get lost when cloneNode is applied.
Another alternative makes use of a side-effect of appendChild to bring a node to the front of the drawing order. If a node already exists in the DOM, then appendChild will remove the node before appending. The following snippet brings an SVG node to the top of the drawing order by making it the last child node of its parent node:
svgNode.parentNode.appendChild( svgNode );
This information was largely derived from http://www.mecxpert.de/svg/swap.html.
The most efficient manner in which to move an element to the top or bottom of a group is most likely the following:
function MoveToTop( svgNode )
{
svgNode.parentNode.appendChild( svgNode );
}
function MoveToBottom( svgNode )
{
svgNode.parentNode.insertBefore( svgNode, svgNode.parentNode.firstChild );
}
see also Removing Element
The <use> Element
Another way of making an element appear above a later element is by using the <use> element to simulate the z-index. This example shows the <line> element being rendered above the <rect> element:
<line id="bottomLine" ... > <rect ... > <use xlink:href="#bottomLine" ...>
Implementing z-index with XSLT
z-index for SVG can be simulated with a simple XSLT script:
<xsl:stylesheet exclude-result-prefixes="giml" version="1.1">
<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="@* | node()">
<xsl:sort select="@z-index" data-type="number"/> <!-- sort the child nodes according to z-index -->
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<xsl:template match="@z-index"/> <!-- remove the z-index attributes -->
</xsl:stylesheet>
The stylesheet takes an SVG augmented with z-index attributes and converts it to an unaugmented SVG document whose nodes have been reordered according to the z-index attributes. This provides the same effect as z-index by taking advantage of the painter algorithm.
