Merged Transforms

From Effects Task Force

Introduction

SVG allows establishing a new user space for graphical or container elements with the 'transform' attribute. The working draft of the CSS 2D transforms specification introduces the CSS property 'transform' with the same objectives and "allows elements rendered by CSS to be transformed in two-dimensional space". The CSS 3D Transforms specification extends CSS 2D transforms by adding a perspective to transformations.

While SVG attributes only apply to SVG elements, the CSS 'transform' property may apply to any markup language that uses CSS styling. Therefore it should be considered to use CSS Transforms in SVG as well. This page discusses issues encountered when trying to merge SVG and CSS transforms. This work is done in preparation of editing the 'merged' CSS Transform specification.

Reading this document

The notations transformation function, transformation type, transform definition, transform definition type and operation type used in the referenced specifications and in this document are just synonyms for basic operations like translate, rotate or scale.

Combining SVG Transforms and CSS Transforms

<rect transform="scale(2)" style="transform: scale(3)"/>

This document considered two options to allow CSS transforms to apply to SVG elements and combine with the existing SVG transform attribute:

  1. Have the SVG 'transform' attribute become a presentation attribute. In this case, the SVG 'transform' just becomes another way to specify the CSS 'transform' property.
  2. Define how two separate transforms could apply to the element. In that case, the SVG and CSS transforms need to 'stack-up' in some clearly defined way.

SVG 'transform' attribute as a presentation attribute

If the SVG 'transform' attribute is a presentation attribute, either the transformation list defined by the SVG attribute, or the one of the CSS property gets applied to the elements user space. If both, the attribute and the property are defined, the CSS property overwrites the value of the SVG attribute.

For the example above the rect would be scaled by a factor of 3, since the CSS 'transform' property overwrites the values of the SVG 'transform' attribute.

CSS Transform and SVG Transforms, get applied to the element, one after the other

For the example above the rect would be scaled by a factor of 6. This option has some disadvantages:

  • At the moment SVG Transforms and CSS Transforms for HTML differ. Authors would need to keep in mind about the differences.
  • Neither CSS's calculated value nor SVG DOM may reflect the currently applied transformation.
  • Implementations stacking model need to account both, CSS Transform and SVG Transform as well as animate motion. This could look like:
    1. SVG Transform
    2. animate motion
    3. CSS Transform
  • or
    1. CSS Transform
    2. SVG Transform
    3. animate motion
  • We may would need to rethink the sandwich model for SMIL Animations.
  • The author has to understand both models and two different syntaxes.
  • Currently the model would be unbalanced: 3D transforms are not applied by SVG Transforms. This could be addressed.


This page just considers the first opportunity SVG 'transform' attribute as a presentation attribute.

Differences between SVG Transforms and CSS Transforms

This section compares SVG Transforms and CSS Transforms.

SVG parser and CSS Parser

SVG parser

The SVG parser supports a list of the following transformation functions: rotate, scale, translate, skewX, skewY or matrix. It should be sufficient to just look at the transform function translate (See The 'transform' attribute for all parsing rules). The notation is in Backus-Naur Form (BNF).

translate:

   "translate" wsp* "(" wsp* number ( comma-wsp number )? wsp* ")"

comma-wsp:

   (wsp+ comma? wsp*) | (comma wsp*)

comma:

   ","

wsp:

   (#x20 | #x9 | #xD | #xA)

It needs to be considered:

  1. White spaces are allowed between the function name and the first brace.
  2. Arguments of transformation functions can be separated by spaces and/or commas.
  3. If a comma separates arguments, just zero or one space after the previous argument is excepted.
  4. Numbers in SVG can have exponents cognizable by a 'e' or 'E'.
  5. Values for all transformation functions are unit less.

CSS parser

The CSS parser supports the following transformation functions in the two-dimensional space: matrix, translate, translateX, translateY, scale, scaleX, scaleY, rotate, skewX, skewY and the following functions in the three-dimensional space: matrix3d, translate3d, translateZ, scaleZ, rotateX, rotateY, rotateZ, perspective.

The named functions use different data types: <number>, <translation-value> and <angle> (<translation-value> can either be <length> or <percentage>).

The parsing rules for the CSS 'transform' property are defined by CSS Values and Units Module Level 3.

  1. Except of <number> all used data types demand units.
  2. The function name is followed by a brace immediately.
  3. If a function has multiple arguments, a comma must separate the arguments with optional white space before and after the comma.

SVG DOM and CSSOM

SVG DOM

The SVG DOM provides three interfaces that are relevant in the context of transforms:

  1. A SVGTransformList that reflects the value of a SVG 'transform' attribute . A SVGTransformList can have multiple SVGTransforms. SVGTransformList provides functions to insert, remove, replace or create SVGTransforms. It is also possible to remove a SVGTransform from one list and add it to another list.
  2. A SVGTransform is an object that reflects a transformation function of type rotate, scale, translate, skewX, skewY or matrix. The type and values of a SVGTransform may change on using one of its setters. SVGTransform provides a SVGMatrix for the current transform, its type, or an angle of type float if the SVGTransform is of type rotate, skewX or skewY. The angle is interpreted as degree.
  3. A SVGMatrix is a 2x3 matrix for a certain transform. It also provides some functionality to multiply the matrix with other matrices or transformation functions. Note that the matrix stay unchanged on every multiplication and returns a new object of type SVGMatrix. Modifications can be made by setting the attributes a, b, c, d, e or f.

All SVG objects are 'live'.

CSSOM

CSS provides some objects and functions to access current transformation settings in CSSOM:

  1. A list of <transform-functions>. Currently it is unspecified how this list should look like. WebKit has a CSSValueList with CSSTransformValues for the style attribute: element.style.getPropertyCSSValue("-webkit-transform"). However, WebKit lacks a list of transformation functions for the computed style. CSSValueList inherits from CSSValue and just provides the setter attribute cssText.
  2. A CSSTransformValue reflects a transformation function of the transform property. Currently supported transformation functions are rotate, scale, scaleX, scaleY, translate, translateX, translateY, skew, skewX, skewY and matrix as well as operation types for three-dimensional operations. CSSTransformValue provides its operation type and a CSSMatrix for the current transform. It does not provide any setter to change the operation type beside the attribute cssText.
  3. A CSSMatrix (extension for three-dimensional transform) represents either a 3x2 matrix or a 4x4 matrix with attributes to read and manipulate coefficients. It also provides some functions to multiply the current matrix with other transformation functions. The result will be a new CSSMatrix. The current matrix remains unchanged. It is not specified if CSSMatrix is "live". If a CSSMatrix is live and a matrix of a certain CSSTransformValue, all changes to the CSSMatrix may affect the operation type of the CSSTransformValue (by changing the type to matrix for example).

CSS also provides the property 'transform-origin' to specify an origin for the list of transformations. This origin may depend on the position and size of the affected element.

To get the computed style for an object you may need to call ViewCSS.getComputedStyle()


var element = document.getElementById('div');
window.getComputedStyle(element).getPropertyCSSValue('transform');

Note that getComputedStyle just provides read only access (See Override and computed style sheet).

DocumentCSS.getOverrideStyle() creates a new style sheet that overrides the computed style without modifying existing user or author style sheets (external, document, inline). The override style sheet allows modifying property values and affects the style of the element immediately. Override style sheet does not override user or author style sheets if they use the !important rule except that itself uses this rule. According to SMIL Animation, override style is also used for animations of the style property. Before any animation step the override style gets cleared and set to the computed style (See The animation sandwich model). However, this feature is not widely implemented [1][2].

Other properties of the CSS 3D Transforms specification like 'transform-style', 'perspective', 'perspective-origin' or 'backface-visibility' don't need to be covered by this document, since 3D extensions were introduced by CSS 3D Transforms. SVG would benefit from this proposal in the same way.

Issues and proposed solutions

Parser issues

CSS parser and SVG parser should be aligned. For backward compatibility the CSS Parser should be compatible with the current SVG Transform syntax. This avoids confusion about different syntaxes.

Issue 1: SVG parser does not allow units for transformation functions

  • The SVG parser just accepts numbers without units. In case of missing units, SVG automatically chooses user units. user units are defined as follows:

    "Note that at initialization, a user unit in the the initial coordinate system is equivalenced to the parent environment's notion of a px unit."

    (See The initial coordinate system). Arguments for rotate, skewX and skewY are interpreted as degree (See The ‘transform’ attribute).

Solutions

  • Follow the interpretation of user units in CSS as well. This needs to be changed in the CSS syntax.
  • (Recommend) Extend the SVG parser to support CSS syntax for 'transform' attribute as well (see [3]).


Issue 2: SVG parser does allow exponents for number

  • The SVG parser allows exponents for numbers like 12e10 or 1E-10.

Solutions

  • The SVG parser already supports scientific notion, but just for the attribute. The property value would not be allowed to use scientific notion.
  • (Recommend) CSS syntax should allow exponents for numbers as well.


Issue 3: SVG parser allows spaces as separator between arguments

  • The SVG parser allows the separation of arguments just with spaces.

Solutions

  • Just allow separating of arguments by whitespaces on SVG attribute. The property value would not be allowed to use just whitespaces for separation.
  • (Recommend) Currently the CSS syntax gets more clarified in CSS3 values, especially for functions. This may allow us to make commas optional (See discussion on www-style).


Issue 4: SVG parser allows white spaces between function name and first opening brace

  • The SVG parser allows white spaces between function name and first opening brace, CSS doesn't.

Solutions

  • Allow whitespaces between function name and first brace in CSS syntax as well.
  • SVG parser should change the behavior with the risk of losing a bit of its backward compatibility. WebKit had just one failing test after experimenting with this rule.
  • (Recommend) Support whitespace between function name and first brace just for SVG attribute. CSS properties won't allow whitespaces there.


Issue 5: CSS supports more white space characters

  • The CSS syntax interprets the following characters as white spaces: "space" (U+0020), "tab" (U+0009), "line feed" (U+000A), "carriage return" (U+000D), and "form feed" (U+000C). SVG just interprets the first four characters as white spaces.

Solutions

  • (Recommend) SVG parser should interpret "form feed" (U+000C) as white space as well.


Issue 6: On separating arguments with a commas on SVG, just one space is allowed between the last argument and the comma

  • On separating arguments with a commas on SVG, just one space is allowed between the last argument and the comma

This issue is invalid. SVG supports multiple whitespaces between last argument and comma as well.

CSSOM issues

To give authors the same possibilities for CSS Transforms like they have for SVG Transforms, CSSOM interfaces should provide more functionalities.

Issue 7: Interaction between CSSMatrix and CSSTransformValue not specified

  • A CSSTransformValue returns a CSSMatrix. It is not defined if this matrix is life or not and how changes to the matrix influence CSSTransformValue. Example: CSSTransformValue has operation type translate. Now you get the CSSMatrix and change attribute a or d to something else than 1 or attribute c and d to something else than 0. Shouldn't the operation type of CSSTransformValue change to matrix?

Solutions

  • CSSMatrix and CSSTransformValue should be "live". Changes on CSSMatrix influence CSSTransformValue as well. We should consider to return a matrix4x4 as well (see discussion on public-fx). The returning matrix4x4 might not be live.


Issue 8: Change operation type of CSSTransformValue

  • Like described in Issue 7, there is a general issue with changing the operation type for CSSTransformValues. Changes on CSSMatrix should change the operation type of the appendant CSSTransformValue to matrix. How can we change the operation type to any other operation?

Solutions

  • SVGTransform (which has a similar meaning like CSSTransformValue) has setters for each supported transformation function. We could consider adding setters to CSSTransformValue for each supported operation type as well. We have cssText but we would force authors to create complete strings with the new transformation function instead of just passing numbers.


Issue 9: Rename CSSTransformValue to CSSTransform

  • CSSTransformValue has the same assignment like SVGTransform. We might consider aligning the naming schema.

Solutions

  • Rename CSSTransformValue to CSSTransform.


Issue 10: Introduce CSSTransformList to collect transformation functions

  • CSS 3D Transforms already mentions a list to collect CSSTransformValues of the 'transform' property but does not define it.

Solutions

  • Introduce the new CSS interface CSSTransformList for all applied transformation functions of a 'transform' property. The list should have the same functionality like SVGTransformList and is "live".

SVG DOM issues

For backward compatibility the SVG DOM still needs to reflect the current transformation functions applied to the presentation attribute.

Issue 11: Interaction of SVG DOMs SVGTransformList and SVGTransform to the CSS property

  • On transforming the SVG attribute transform' to a presentation attribute, the interaction of SVG DOM with CSSOM must be clarified. While an SVG attribute has a one-dimensional hierarchy where the value can just be influenced by the unique SVGTransformList, CSS had different cascading. Like described for CSSOm above, it is difficult to map cascading to the one-dimensional hierarchy, since different style sheets can affect the style of an element and there for can have different affects to computed style. Computed itself style doesn't allow modifications.

Solutions

  • Let SVG DOM reflect the override style. Modifications on SVG DOM objects cause changes on override style. Problems:
    • Override style does not necessarily reflect the actual style of an element. Override style may not override importance rules in user or author style sheets.
    • Using override style will cause conflicts with SMIL animations, which use override style as well. It wouldn't be possible to differ between baseVal and animVal.
  • (Recommend) Let SVG DOM point to an own style sheet.
    • UAs need to create a new author style sheet for presentation attributes (See 6.4 Specifying properties using the presentation attributes). Let SVG DOM point to this style sheet.
    • Because the SVG DOM just points to this style sheet, other user or author style sheets can not get covered by SVG DOM. If you want to use SVG DOM, make sure that just the presentation attribute sets the style for 'transform' on a certain element.
    • This would be a backward compatible solution with potential to get improved in the future on CSSOM changes.


Issue 12: Future of SVG DOM

  • Should we mark SVG DOM parts for 'transform' as deprecated?

Solutions

  • Update SVG DOM with every current and future feature from CSS Transforms. New SVG objects need to be created to reflect the 3D functionality, existing SVG objects need to be updated. This could mean to maintain SVG DOM in CSS Transforms as well if a certain future affects SVG DOM.
  • (Recommend) Mark SVG DOM parts for 'transform' as deprecated and don't update SVG DOM to new features in CSS Transforms. However, SVG DOM still needs to get supported for a while to be backward compatible. New features won't be included in SVG DOM and SVG DOM might not be aware of the currently applied transformation. SVGTransform could raise a 'not supported' error in this case. Authors should use the capabilities of CSSOM and CSS Transforms directly.

Resolutions of SVG WG

Meeting Minutes 2012-01-26 Issue 11, 12

Follow recommendations of Issues 11 and 12. SVG DOM should not be marked as deprecated but is not updated. Future SVG DOM version might address this.


Meeting Minutes 2012-02-16 Issue 1-5

Follow recommendations of Issues 11 and 12. SVG DOM should not be marked as deprecated but is not updated. Future SVG DOM version might address this.

adopt dirks' svg parser proposal for transform syntax in svg This actually solves Issues 1-5