SVG 2 Requirement: Support the z-index.
Resolution: We will add Jonathan Watt's z-index proposal to SVG 2.
Purpose: Allow reordering (such as when a planet orbits the sun). Reordering without script support (e.g. CSS :hover).
Owner: Jonathan (Action 3002).
The SVG 2 rendering model will follow the rules defined by the Compositing and Blending specification.
Resolution: Seattle/Paris 2012 F2F day 3.
Owner: Nikos (Action 3332).
Implementations of SVG are expected to behave as though they implement a rendering (or imaging) model corresponding to the one described in this chapter. Real implementations may choose to implement the model in the way that they see fit, but the result on any device supported by the implementation must, in most cases, match this model.
The appendix on conformance requirements describes the extent to which an actual implementation may deviate from this description. In practice an actual implementation may deviate slightly because of limitations of the output device (e.g. only a limited range of colors might be supported) and because of practical limitations in implementing a precise mathematical model (e.g. for realistic performance curves are approximated by straight lines, the approximation need only be sufficiently precise to match the conformance requirements).
SVG uses a "painters model" of rendering. Paint is applied in successive operations to the output device such that each operation paints onto some area of the output device, possibly obscuring paint that has previously been layed down. After each object or group is painted, it becomes part of the background for the next painting operation. SVG 2 supports advanced blending modes and compositing operations that control how each painting operation interacts with the background. The rules governing these painting operations are outlined in the Compositing and Blending Specification.
Elements in SVG are positioned in three dimensions. In addition to their
position on the x and y axis of the SVG viewport, SVG elements are also
positioned on the z-axis. The position on the z-axis defines the order that
they are painted.
Along the z-axis, elements are grouped into 'stacking contexts', each stacking
context has an associated stack level.
A stack level may contain one or more child nodes - either child
stack levels, graphics elements, or ‘g’ elements.
graphics elements and ‘g’ elements within single
stack level are painted in document order - that is, they are painted
in the order that they are defined in the document.
Each stack level is assigned an integer value that defines it's
position on the z-axis relative to other stack levels within the same
stacking context. Lower values are painted first, and so
elements in a stack level with a higher value will paint over one
with a lower value.
By default, everything is placed in stack level zero.
See the CSS 2.1 specification for the definition
of ‘z-index
’. [CSS21]
The ‘z-index
’ property allows an element to be assigned to a
stack level.
The rules governing behaviour for SVG elements with the ‘z-index
’
property specified are outlined below:
CSS specifies a
property named ‘z-index
’. The CSS rules
that define the effect of the ‘z-index’ property
were written specifically for the CSS box model, and those rules do not make
sense as they stand for most SVG elements (most SVG elements do not participate
in or establish a CSS box model layout). This section specifies how
implementations must handle the ‘z-index
’ property on elements in the SVG
namespace.
Contrary to the rules in CSS 2.1, the ‘z-index
’ property applies to all SVG
elements regardless of the value of the ‘position
’ property, with one exception:
as for boxes in CSS 2.1, outer ‘svg’ elements must be positioned for ‘z-index
’
to apply to them.
The ‘z-index
’ property specifies:
Values have the following meanings:
Here is a simple example:
<svg xmlns="http://www.w3.org/2000/svg"> <rect x="0" width="100" height="100" fill="red" z-index="-1"/> <rect x="40" width="100" height="100" fill="lime"/> <rect x="80" width="100" height="100" fill="blue" z-index="1"/> <rect x="60" width="100" height="100" fill="aqua"/> <rect x="20" width="100" height="100" fill="yellow" z-index="-1"/> </svg>
In this example there are three stack levels: -1, 0 (the default) and 1. The red and yellow rects are in stack level -1, the lime and aqua rects are in stack level 0 (the default), and the blue rect is in stack level 1. Going from lowest stack level to highest, and painting the elements in each stack level in document order, the painting order is: red, yellow, lime, aqua, blue.
A new stacking context must be established at an SVG element for its descendants if:
z-index
’ property applies to the element and its computed
value is an integeroverflow
’ property is a value other than visibleopacity
’ property applies to the element and it has a
computed value other than 1mask
’ property applies to the element and it has a computed
value other than nonefilter
’ property applies to the element and it has a
computed value other than noneStacking contexts and stack levels are conceptual tools used to describe the order in which elements must be painted one on top of the other when the document is rendered, and for determining which element is highest when determining the target of a pointer event. Stacking contexts and stack levels do not affect the position of elements in the DOM tree, and their presence or absence does not affect an element's position, size or orientation in the canvas' X-Y plane - only the order in which it is painted.
Stacking contexts can contain further stacking contexts. A stacking context is atomic from the point of view of its parent stacking context; elements in ancestor stacking contexts may not come between any of its elements.
Each element belongs to one stacking context. Each element in a given stacking context has an integer stack level. Elements with a higher stack level must be placed in front of elements with lower stack levels in the same stacking context. Elements may have negative stack levels. Elements with the same stack level in a stacking context must be stacked according to document order.
With the exception of the ‘foreignObject’ element, the back to front stacking order for a stacking context created by an SVG element is:
Since the ‘foreignObject’ element creates a "fixed position containing block" in CSS terms, the normative rules for the stacking order of the stacking context created by ‘foreignObject’ elements are the rules in Appendix E of CSS 2.1.
In the following example, the ‘z-index
’ property on the ‘g’
element is set to zero. This creates a new stacking context to contain the
‘g’ element's children without moving the ‘g’ to a different
level in the document's root stacking context:
<svg xmlns="http://www.w3.org/2000/svg"> <g z-index="0"> <!-- this is a self contained graphic --> <rect x="40" width="100" height="100" fill="lime" z-index="1"/> <rect x="20" width="100" height="100" fill="yellow"/> </g> <rect x="60" width="100" height="100" fill="aqua"/> <rect x="0" width="100" height="100" fill="red" z-index="-1"/> </svg>
The example's root stacking context contains two stack levels: -1 and 0. The red
‘rect’ is in level -1, and the ‘g’ element and aqua ‘rect’ are in level 0. Inside
stack level 0, the ‘g’ element's ‘z-index
’ property creates a new nested stacking
context at the ‘g’ for the ‘g’ element's children. In this child stacking
context there are two stack levels: 0 and 1. The yellow ‘rect’ is in level 0 (the
default), and the lime ‘rect’ is in level 1.
Painting of this example starts with the stack levels of the root stacking context. First the red rect is painted in level -1, then in level 0 the ‘g’ element is painted followed by the aqua rect. When the ‘g’ element is painted, the child stacking context that its z-index created and all of that context's stack levels are also painted. In this child stacking context, first the yellow rect in level 0 is painted, followed by the lime rect in level 1. It's only after the ‘g’ and the stacking context that it creates has been painted that the aqua rect is painted. Note that this means that although the z-index of 1 for the lime rect is a higher value than the (implicit) z-index of 0 for the aqua rect, the containment provided by the ‘g’'s child stacking context results in the aqua rect painting over the lime rect. The painting order is therefore: red, yellow, lime, aqua.
Individual graphics elements are treated as if they are non isolated groups, the components (fill, stroke, etc) that make up a graphic element (See Painting shapes and text) being members of that group. See How groups are rendered.
Grouping elements, such as the ‘g’ element (see container elements
) create a compositing group. The Compositing and Blending
specification normatively describes how to render compositing groups.
In SVG, effects may be applied to a group. For example, opacity, Filter Effects
or masking. These effects are applied to the rendered result of the group
immediately before any transforms on the group are applied, which are applied
immediately before the group is blended and composited with the
group backdrop. Applying any such effects to a group makes that
group isolated.
When rendering an SVG group, unknown elements and their children are discarded
from the group.
Thus, rendering a compositing group follows the following steps:
If the group is isolated:
See the CSS Color Module Level 3 for the definition
of ‘opacity
’. [CSS3COLOR]
The ‘opacity
’ property specifies how opaque a given
graphical element or container element will be when it is
painted to the canvas. When applied to a container element,
this is known as group opacity, and when applied to
an individual rendering element, it is known as object
opacity. The principle for these two operations however
is the same.
There are several other opacity-related properties in SVG:
fill-opacity
’, which specifies the opacity of a fill
operation;stroke-opacity
’, which specifies the opacity of a stroking
operation;solid-opacity
’, which specifies the opacity of a solid color
paint server; andstop-opacity
’, which specifies the opacity of a gradient stop.These four opacity properties are involved in intermediate rendering operations.
Object and group opacity however can be thought of as a post-processing operation.
Conceptually, the object or group to which ‘opacity
’ applies
is rendered into an RGBA offscreen image. The offscreen image as whole is then blended
into the canvas with the specified ‘opacity
’ value used uniformly
across the offscreen image.
Thus, the presence of ‘opacity
’ causes the group to be
isolated.
The ‘opacity
’ property applies to the following SVG elements:
‘svg’, ‘g’, ‘symbol’, ‘marker’,
‘a’, ‘switch’, graphics elements and
text content child elements.
The following example illustrates various usage of the ‘opacity
’
property on objects and groups.
<svg xmlns="http://www.w3.org/2000/svg" width="600" height="175" viewBox="0 0 1200 350"> <!-- Background blue rectangle --> <rect x="100" y="100" width="1000" height="150" fill="blue"/> <!-- Red circles going from opaque to nearly transparent --> <circle cx="200" cy="100" r="50" fill="red" opacity="1"/> <circle cx="400" cy="100" r="50" fill="red" opacity=".8"/> <circle cx="600" cy="100" r="50" fill="red" opacity=".6"/> <circle cx="800" cy="100" r="50" fill="red" opacity=".4"/> <circle cx="1000" cy="100" r="50" fill="red" opacity=".2"/> <!-- Opaque group, opaque circles --> <g opacity="1"> <circle cx="182.5" cy="250" r="50" fill="red" opacity="1"/> <circle cx="217.5" cy="250" r="50" fill="green" opacity="1"/> </g> <!-- Group opacity: .5, opacity circles --> <g opacity=".5"> <circle cx="382.5" cy="250" r="50" fill="red" opacity="1"/> <circle cx="417.5" cy="250" r="50" fill="green" opacity="1"/> </g> <!-- Opaque group, semi-transparent green over red --> <g opacity="1"> <circle cx="582.5" cy="250" r="50" fill="red" opacity=".5"/> <circle cx="617.5" cy="250" r="50" fill="green" opacity=".5"/> </g> <!-- Opaque group, semi-transparent red over green --> <g opacity="1"> <circle cx="817.5" cy="250" r="50" fill="green" opacity=".5"/> <circle cx="782.5" cy="250" r="50" fill="red" opacity=".5"/> </g> <!-- Group opacity .5, semi-transparent green over red --> <g opacity=".5"> <circle cx="982.5" cy="250" r="50" fill="red" opacity=".5"/> <circle cx="1017.5" cy="250" r="50" fill="green" opacity=".5"/> </g> </svg>
In the example, the top row of circles have differing opacities, ranging from 1.0 to 0.2. The bottom row illustrates five ‘g’ elements, each of which contains overlapping red and green circles, as follows:
SVG supports three fundamental types of graphics elements that can be rendered onto the canvas:
Shapes and text can be filled (i.e., apply paint to the interior of the shape) and stroked (i.e., apply paint along the outline of the shape).
For certain types of shapes, marker symbols (which themselves can consist of any combination of shapes, text and images) can be drawn at positions along the shape boundary. Each marker symbol is painted as if its graphical content were expanded into the SVG document tree just after the shape object which is using the given marker symbol. The graphical contents of a marker symbol are rendered using the same methods as graphics elements. Marker symbols are not applicable to text.
The order in which fill, stroke and markers are painted is determined
by the ‘paint-order
’ property. The default is that
fill is painted first, then the stroke, and then the
marker symbols. The marker symbols are rendered in order along
the outline of the shape, from the start of the shape to the
end of the shape.
Each fill and stroke operation has its own opacity settings; thus, you can fill and/or stroke a shape with a semi-transparently drawn solid color, with different opacity values for the fill and stroke operations.
The fill and stroke operations are entirely independent painting operations; thus, any stroke applied to the shape will be painted on top of part of the fill.
SVG supports numerous built-in types of paint which can be used in fill and stroke operations. These are described in Paint Servers.
When a raster image is rendered, the original samples are "resampled" using standard algorithms to produce samples at the positions required on the output device. Resampling requirements are discussed under conformance requirements.
As in HTML [HTML, 10.4.2], all animated images with the same absolute URL and the same image data are expected to be rendered synchronised to the same timeline as a group, with the timeline starting at the time of the least recent addition to the group.
When a user agent is to restart the animation for an img element showing an animated image, all animated images with the same absolute URL and the same image data in that img element's node document are expected to restart their animation from the beginning.
SVG allows any painting operation to be filtered. (See Filter Effects.)
In this case the result must be as though the paint operations had been applied to an intermediate canvas initialized to transparent black, of a size determined by the rules given in Filter Effects then filtered by the processes defined in Filter Effects.
SVG supports the following clipping/masking features:
Both, clipping and masking, are specified in the module CSS Masking [CSS-MASKING].
SVG document fragments can be semi-opaque.
In accordance with the Compositing and Blending specification, the ‘svg’ element always creates an isolated group.
When the SVG document is a top-level document, the top level SVG element is considered to be the page group and is composited with a backdrop of white with 100% opacity. For all other referencing modes, there is no page group. The SVG document is composited into the parent document with opacity preserved.
See the Cascading Style Sheets Level 2 Revision 1 (CSS 2.1)
Specification [CSS21] for the definition of
‘overflow
’.
element | initial | ua styleshet | auto[6] | visible | hidden | scroll |
---|---|---|---|---|---|---|
standalone svg | visible[2] | hidden | hidden | visible | hidden | scroll |
inner svg | visible[2] | hidden | hidden | visible | hidden | scroll |
pattern[1] | visible | hidden[4] | hidden | visible | hidden | hidden |
hatches[1] | visible | hidden[5] | hidden | visible | hidden | hidden |
marker[1] | visible | hidden[3] | hidden | visible | hidden | hidden |
symbol | visible | n/a | hidden | visible | hidden | hidden |
image | visible | hidden | hidden | visible | hidden | hidden |
iframe | visible | hidden | hidden | visible | hidden | hidden |
foreignObject | visible^ | hidden | hidden | visible | hidden | hidden |
Table footnotes:
The ‘overflow
’ property has the same parameter values and has the
same meaning as defined in CSS 2.1
([CSS21], section 11.1.1);
however, the following additional points apply:
overflow
’ property can apply.
If the ‘overflow
’ property has the value
hidden or scroll, a clip,
the exact size of the viewport is applied.
overflow
’ property can apply, if
the ‘overflow
’ property has the value hidden or scroll,
the effect is that a new clipping path in the shape of a rectangle is created.
The result is equivalent to defining a ‘clipPath’ element whose
content is a ‘rect’ element which defines the equivalent rectangle,
and then specifying the <uri> of this ‘clipPath’ element on the
‘clip-path
’ property for the given element.overflow
’ property has a value other than
hidden or scroll,
the property has no effect (i.e., a clipping rectangle is not created).
This is needed still
CSS implies that 'auto' should be clipped rather than visible, do we want to follow that or not?
Check on resolution that we made for this - Can't find resolution, but see https://lists.w3.org/Archives/Public/www-svg/2012May/0096.html Browsers all seem to implement auto = hidden.overflow
’ property has the value hidden
or scroll, then the user agent will
establish an initial clipping path equal to the bounds of the initial
viewport; otherwise, the initial
clipping path is set according to the clipping rules as defined in CSS 2.1
([CSS21], section 11.1.1).
This seems superfluous given what is written in bullet point 1, but we might
need to say something special for the visible value - check the CSS text.
overflow
’ property on the outermost svg element is ignored
for the purposes of visual rendering and the initial clipping path is set to
the bounds of the initial viewport.
Note that the value hidden still means that
no scrolling user interface should be provided.overflow
’ as defined
in [CSS21-overflow]
is 'visible', and this applies also to the outermost svg element; however,
for child elements of an SVG document, SVG's user agent style sheet
overrides this initial value and sets the ‘overflow
’ property on the
‘svg’, ‘image’, ‘pattern’ and ‘iframe’ elements
to the value hidden.overflow
’ is auto. In the UA style sheet,
overflow is overriden for svg, image, pattern, and frame to be hidden by default.
Get rid of this
As a result of the above, the default behavior of SVG user agents is to
establish a clipping path to the bounds of the initial
viewport and to establish a new clipping
path for each element which
establishes a new viewport and each ‘pattern’ and
‘marker’ element.
When an ‘svg’ element is either the root element in the
document or is embedded within a document whose layout is determined
according to the layout rules of CSS, then the user agent must
establish an initial clipping path for the SVG document fragment. The
‘overflow
’ property along with additional SVG
user agent processing rules determine the initial clipping path which
the user agent establishes for the SVG document fragment:
In SVG 1.1 the ‘overflow
’ and ‘clip
’ property
defintions follow at this point.