Clean, quick, and easy solutions published as of the date of this answer are unsatisfactory. They are based on the erroneous assertion that the zG order is missing the z order. Libraries are not needed either. A single line of code can perform most operations to control the order of z objects or groups of objects that may be required when developing an application that moves 2D objects in XYZ space.
Order Z definitely exists in SVG document fragments
What is called an SVG document fragment is a tree of elements derived from a base node of type SVGElement. The root node of the SVG document fragment is SVGSVGElement, which corresponds to the HTML5 <svg> tag . SVGGElement matches the <g> tag and allows aggregation of child elements.
Having the z-index attribute in SVGElement, as in CSS, would have defeated the SVG rendering model. Sections 3.3 and 3.4 of the W3C Recommendation SVG v1.1, 2nd Edition, state that fragments of an SVG document (descendant trees from SVGSVGElement) are rendered using the so-called deep tree search. This scheme is in any sense of the word.
Z-order is essentially a shortcut to computer vision, avoiding the need for real 3D rendering with the complexities and computational requirements of ray tracing. A linear equation for the implicit z-index of elements in an SVG document fragment.
z-index = z-index_of_svg_tag + depth_first_tree_index / tree_node_qty
This is important because if you want to move a circle that was below the square above it, you simply insert a square in front of the circle. This can be easily done in JavaScript.
Support Methods
SVGElement instances have two methods that support simple and easy z-order manipulation.
- parent.removeChild (child)
- parent.insertBefore (child, childRef)
The correct answer that doesn't mess up
Because SVGGElement ( <g> tag ) can be removed and pasted as easily as SVGCircleElement or any other shape, image layers typical of Adobe products and other graphical tools can be easily implemented using SVGGElement. This JavaScript is essentially a Move Below command.
parent.insertBefore(parent.removeChild(gRobot), gDoorway)
If the robot layer drawn as children of SVGGElement gRobot was before the doorway was drawn as children of SVGGElement gDoorway, the robot is now behind the doorway, because now the z-order of the doorway is one plus the z-order of the robot.
The Move Above team is almost as simple.
parent.insertBefore(parent.removeChild(gRobot), gDoorway.nextSibling())
Just think a = a and b = b to remember this.
insert after = move above insert before = move below
Leave the DOM in a view compatible state
The reason that this answer is correct is because it is minimal and complete, and, like the internal components of Adobe products or other well-designed graphic editors, it leaves the internal representation in a state that matches the representation created during rendering.
Alternative but limited approach
Another commonly used approach is to use CSS z-index in combination with several fragments of SVG documents (SVG tags) with an almost transparent background in all but the bottom. Again, this negates the elegance of the SVG rendering model, making it difficult to move objects up or down in z-order.
NOTES:
- ( https://www.w3.org/TR/SVG/render.html v 1.1, 2nd edition, August 16, 2011)
3.3 Rendering order elements in an SVG document fragment have an implicit drawing order, with the first elements in the SVG document fragment being “painted over” first. Subsequent elements are painted over previously painted elements.
3.4 How groups are rendered Grouping elements such as the 'g element (see Container Elements) create a temporary separate canvas initialized with transparent black on which children are painted. After the group completes, all the filter effects specified for the group are used to create the modified temporary canvas. A modified temporary canvas is superimposed on the background, taking into account any masking parameters at the group level and opacity parameters in the group.