[css3-transforms] transform-origin syntax: 3D vs. background-position

(BCC'd www-style, replies should go to public-fx)

Bug: https://www.w3.org/Bugs/Public/show_bug.cgi?id=15432

What should something like "transform-origin: left bottom 10px" do?
According to the old 2D Transforms spec and the current merged spec,
it places the origin at the left edge of the element's border box,
10px from the bottom, with z = 0.  According to the old 3D transforms
spec, it places the origin at the bottom left of the element's border
box, with z = 10px.  IE10 Developer Preview, Firefox 13.0a1, and
Chrome 18 dev all follow the old 3D spec.  Opera Next 12.00 alpha
(which does not implement 3D transforms) appears to follow neither
spec, and treats it like "left top" as far as I can see, which I admit
that I don't understand at all.

The reasoning behind the 2D Transforms syntax is to match the CSS3
definition of background-position:
<http://dev.w3.org/csswg/css3-background/#the-background-position>.
If I test with "background-position: bottom 25px right 100px", Firefox
and Chrome seem to ignore it, while IE and Opera seem to treat it per
spec the same as "100px 25px" (my element is 50px tall and 200px
wide).  However, background-position is two-dimensional, and it's not
obvious how to expand it to account for a z-offset.

I should point out that the ambiguity only exists in the very special
case of "keyword keyword length", and only if the second keyword is
not "center".  In any other case, it's unambiguous.  For instance,
"left bottom 10px" is ambiguous, but "bottom 10px left" is not --
"left" is not valid for the third coordinate of the 3D
transform-origin syntax.

There are a lot of possible solutions, most of which have been
proposed before in various places and some of which I just made up
now:

1) Go with the 3D transforms syntax, and leave transform-origin
incompatible with background-position.

2) Make transform-origin consistent with background-position, and
don't let it specify a Z offset.  Introduce a new transform-origin-z
property that authors have to use to get a Z offset.

3) Make transform-origin consistent with background-position, and
don't let it specify a Z offset.  If authors want a Z offset, they can
do translateZ() before and after the transform, with no shorthand.

4) Make transform-origin consistent with background-position, and
require a slash before the Z offset.  The slash might be required
always, or only in cases that would otherwise be ambiguous.

5) Go with the 3D transforms syntax, and change background-position
back to its old restricted syntax.  Make sure calc() is defined so
that the same effects can be achieved with the old syntax.  E.g.,
"background-position: left bottom 10px" could become
"background-position: left calc(bottom - 10px)".

6) Go with both syntaxes, and resolve ambiguous cases in favor of the
3D transform syntax.  Thus "left bottom 10px" would be parsed using
the 3D transform syntax, but "bottom 10px left" or "left 0px bottom
10px" would be parsed like the background-position syntax.  (It's
always possible to rewrite ambiguous cases so that they don't parse as
3D transform syntax, by adding "0px" after the first keyword or
swapping the order, so this doesn't remove any power from authors, but
it might be confusing.)

7) Go with both syntaxes, and resolve ambiguous cases in favor of the
background-position syntax.  Thus "left bottom 10px" would be parsed
using the background-position syntax, but "left 100% 10px" would be
parsed like the 3D transform syntax.  (It's always possible to rewrite
ambiguous cases so that they don't parse as background-position
syntax, by replacing a keyword with 0% or 100%, so this doesn't remove
any power from authors, but it might be confusing.)

This was discussed at an informal CSS Transforms editors' meeting
yesterday, and no conclusion was reached.  Not all these options were
suggested there.  Here are some observations on the advantages and
disadvantages of each:

* All of the proposed syntaxes are equally powerful as long as calc()
is supported properly.  Moreover, even if calc() isn't supported
properly, you can always emulate the effect by using translate()
directly.  So this is just a question of which syntactic sugar is
nicest, not of what we let authors do.
* Option (1) would require no implementations to change (I think).
Option (5) would require IE and Opera to change.  Every other option
would require all implementations to change.
* Options (1) and (5) make transform-origin very simple: it's one to
three coordinates.  Option (5) makes background-position equally
simple.  IMO, authors would probably guess that "5px 7px 10px" means
"x = 5px, y = 7px, z = 10px", and would probably guess that "left
bottom 10px" means "x = left, y = bottom, z = 10px".  I'm almost sure
no one would guess it means "x = left, y = bottom - 10px".
* Options (2), (3), (4), (5), and (7) make any valid
background-position have the same meaning in transform-origin (they're
consistent).  Options (1) and (6) make them inconsistent.
* Options (2), (3), and (4) make the Z-component of the origin
markedly inconsistent with the X- and Y-components.
* Option (5) would need discussion on www-style, not just public-fx.
* Options (6) and (7) are confusing.  I present them just for the sake
of completeness.  You can ignore them if you want, unless someone
really thinks they're a good idea.

Personally, I favor (5).  I feel the new background-position syntax is
hard to understand, and is obsoleted by calc().  "background-position:
right 5px bottom" would be clearer as "background-position: calc(right
- 5px) bottom", IMO, and the latter requires less complexity in specs
and implementations, since it needs to work anyway.

Failing (5), I prefer (1), both because it stops the new
background-position syntax from spreading and because it matches
implementations.  I don't like any of the other options, because they
require implementations to change how transform-origin works and I
think the way it currently works is ideal -- I actively prefer it to
background-position even in the two-dimensional case.

The editors of CSS Transforms don't seem to agree with me, though, and
mostly appear to prefer option (2) if I'm not mistaken.  We agreed to
take it to the list.  What does everyone else think?

Received on Wednesday, 22 February 2012 16:25:57 UTC