FX-Taskforce/CSS-Transforms-Review

From SVG

Hi CSS Working Group.

The SVG Working Group recently discussed the proposals for CSS 2D and 3D Transform modules[1,2]. We appreciate and support the desire to add transformation functionality to CSS, and we would like to work with the CSS WG to ensure compatibility between the CSS WG and SVG WG work in this area. Below are some questions/comments.


We would like to know if there are any published use cases and requirements for the proposed modules. It would help us if we could review the proposals from a better understanding of the particular use cases and requirements you wish to support. In particular, as discussed below, we would like to know what are the use cases for supporting general 4x4 3D transformation matrices, as opposed to affine 3D plus perspective projection.


Are translateX/Y/Z and scaleX/Y/Z necessary, given that the proposal includes translate3d and scale3d? There seems to be little benefit to this redundancy. In response to minutes from our F2F where we were discussing CSS Transforms, Dean said[3]:

> While these might shortcuts look like syntactic sugar, they allow for > something important - which is the ability to break a transform list into > components that can manipulated individually. This is especially important > when you're animating between transforms (not necessarily with CSS > Animations, even JS gets the benefit). Flattening all the transform > operations is a lossy process (not in the final matrix result, but you lose > the list).

This seems to be an argument against removing translateX/Y/Z etc. and requiring authors to use matrix3d(), rather than an argument against 'translate' etc, taking optional arguments. We understand that flattening the matrix is a lossy process, however isn't translateZ(40) = translate3d(0 0 40)? You can still get that individual translation component out of the list.

> In general I'm not sure there is benefit in minimising the syntax. What is > the cost?

The cost is minimal by itself, but these things add up, and it seems the benefit is minimal too. To do y-translation in SVG, you just do translate(0 40); it doesn't seem particularly onerous to specify the 0.


The SVG Working Group appreciates that the CSS 3D Transforms proposal tries to use naming consistent with SVG Transforms. Regarding this, has the CSS Working Group considered extending the 'scale', 'translate' and 'rotate' SVG transform items to allow for both 2D and 3D transforms to be applied based on the values passed in (as opposed to creating extra scale3d et. al. properties)?

For example:

* scale(<sx> [<sy> [<sz>]])
* translate(<tx> [<ty> [<tz>]])
* rotate(<rotate-angle> <nx> <ny> <nz> [<cx> <cy> <cx>])

Since backward compatibility is important we tested current browsers. In most, the entire transform attribute is ignored if it contains a transform item that is invalid under the limitations of SVG 1.1 transforms (such as a scale() with three values). In Opera, all of the transform items up to the invalid transform item are applied, and only the invalid item and those that follow are ignored.


In SVG and the CSS 2D Transforms proposal, 'translate' and 'scale' both contain optional parameters so that both symmetric and asymmetric transformation of all axes are possible. Has the CSS Working Group considered optional parameters for scale3d, translate3d and rotate3d as well?

For example:

* scale3d(<sx> [<sy> <sz>])
* translate3d(<tx> [<ty> <tz>])
* rotate3d(<angle> <nx> <ny> <nz> [<cx> <cy> <cz>])


Is there any reason a 4x4 transformation model was chosen? OpenVG uses a 3x3 matrix interface and SVG devices that implement CSS 3D Transforms as currently specified will not be able to take advantage of the OpenVG API. There exist implementations of SVG on top of OpenVG (such as AlexVG) which otherwise would need to implement their own transform pipeline. One of the advantages of using OpenVG is existing implementations get hardware acceleration. Note that the current proposed SVG Transforms Module model is compatible with OpenVG and OpenGL. We would like to see use cases for specifying 4x4 matrices which aren't simply affine 3D transformations plus a single point projection transformation.

Dean in his mail said: > I suggest you stick with 4x4 matrices over 3x3. I wouldn't let the fact > that OpenVG is 3x3 (is it? I read this in the minutes but didn't check) > impact the decision.

We believe so. On http://www.khronos.org/openvg/ it states "Image drawing uses a 3x3 perspective transformation matrix".

> Cameron says that "general 3d effects are not useful" - maybe I > misunderstood that?

The intent of Cameron's comment was more along the lines of wondering what effects that you can achieve with a general 4x4 matrix that aren't supported by affine 3D plus perspective projection.


Is there a reason for allowing perspective to be part of the transform list as well as being a separate property? Authors could specify multiple perspective transformations (and possibly also the perspective property), which would produce odd results.

For example: transform="translate(...) perspective(...) scale(...) rotate3d(...) perspective(...)"


The SVG Working Group thinks that 'transform-origin' is a really good property, however it has the following issues:

  • Its initial value is "50% 50% 0", which is incompatible with how SVG transforms work in the absence of transform-origin (i.e., SVG behaves as if "0 0 0" is the default value). Anne suggested on IRC[4] that SVG elements could have an initial value of "0 0 0" while other elements have "50% 50% 0", but this might be confusing for authors.
  • The property appears to be overloaded in that it seems that the coordinate space that the property operates in depends on the values. Is this correct?
  • If lengths are specified for transform-origin is the length measurement taken from the origin of the current coordinate system or from the top left hand corner of the object's bounding box? What if the property was broken up into transform-origin-bbox and transform-origin-userspace or something similar?


We discussed 'transform-style' which automatically orders rendering of objects based on Z position of the object when set to "preserve-3d". As Dean mentions, rendering of the content may be difficult for SVG UAs given that SVG uses the painter's algorithm. One possibility is to only allow re-ordering of objects based on their Z position when inside a container with the transform-style property set. A similar option is to introduce a container element <layeredG>, <g3d> or <layer> where the order of rendering the child elements is based on their Z position and not the document order. This would help restrict the complexity when rendering objects with 3D transforms in SVG. The SVG Working Group believes this is one possible solution which helps reduce the complexities involved in implementing SVG Transforms. Any comments the CSS Working Group has regarding this would be greatly appreciated.


Objects with depth may not always be parallel to the screen (as a result of rotations). Two problems can occur as a result of this. Firstly, what is the Z position when an object is not parallel to the screen (e.g. if it has a rotateY applied to it)? Is it the "closest" appearing Z point, the "furthest" appearing Z point, the center of the object, the top left point, or the 4th column 3rd row of the transform matrix? Secondly, if two objects have the same Z position, are both not parallel to the screen and intersect, are the objects clipped or is one rendered on top of the other in document order?


The CSS Transform proposal says in the introduction [[ Any value other than ‘none’ for the transform results in the creation of both a stacking context and a containing block. The object acts as though position: relative has been specified, but also acts as a containing block for fixed positioned descendants. The position on the Z axis of a transformed element does not affect the order within a stacking context. With elements at the same z-index, objects are drawn in order of increasing z position. ]]

z-index is only mentioned once in the proposal. We assume that this is z-index as defined in the CSS 2.1 specification[5] and uses a stacking context as described in Appendix E. How would this work with documents that do not establish a stacking context (or alternatively, put everything in one stacking context) such as SVG?


In CSS Transforms, rotate() takes an <angle> value, which must have a unit. In SVG, this takes a unitless number (assumed to be in degrees). The SVG WG is open to exploring the addition of units in transform values, including angle units, into SVG. We would expect to allow 'deg', 'grad', and 'rad' as units, as already supported in some other SVG attributes, and perhaps to allow for the 'turn' unit also. For backwards compatibility, we would want both SVG and CSS Transforms to allow unitless values as well, with degrees as the default if no unit is provided.

Finally, the CSS list syntax states that "If a function takes more than one argument, the arguments are separated by a comma (‘,’) with optional whitespace before and after the comma." The SVG specification allows as a list-delimiter token a non-zero-length string consisting of an optional comma and any number of whitespace characters, (\s+|\s*,\s*) in perl regex syntax. The SVG WG intends to allow this as a general rule in any SVG attributes, to make authoring and implementing easier and more consistent. We would like for CSS Transforms to allow this as well.


[1] http://dev.w3.org/cvsweb/~checkout~/csswg/css3-2d-transforms/Overview.html?rev=1.3&content-type=text/html;%20charset=iso-8859-1 [2] http://dev.w3.org/cvsweb/~checkout~/csswg/css3-2d-transforms/Overview.html?rev=1.1&content-type=text/html;%20charset=iso-8859-1 [3] http://www.w3.org/mid/DE386490-A480-4D9F-939C-F17C554925B6@apple.com [4] http://krijnhoetmer.nl/irc-logs/whatwg/20090225#l-201 [5] http://www.w3.org/TR/CSS21/visuren.html#propdef-z-index [6] http://www.w3.org/TR/CSS21/zindex.html