W3C home > Mailing lists > Public > www-style@w3.org > July 2014

Re: [css-transforms] Making 'transform' match author expectations better with specialized 'rotate'/etc shorthands

From: Alan Gresley <alan@css-class.com>
Date: Wed, 16 Jul 2014 22:20:56 +1000
Message-ID: <53C66E28.4000801@css-class.com>
To: Shane Stephens <shans@google.com>, Dirk Schulze <dschulze@adobe.com>
CC: "Tab Atkins Jr." <jackalmage@gmail.com>, Alan Stearns <stearns@adobe.com>, Dean Jackson <dino@apple.com>, www-style list <www-style@w3.org>
On 16/07/2014 7:32 PM, Shane Stephens wrote:
>>
>>> Yes, order matters when you need the transforms to interact.  When you
>>> don't (when they're all "local"), there's one specific order that does
>>> what you want.
>>
>> “local” seems to be confusing here. All transformations are local for an
>> element and take affect on rendering into the parents graphics context.
>
>
> Yeah, local is confusing - all transforms act locally. I think what Tab
> means is that there's one specific order for which transforms appear to act
> globally as well.

Why is local confusing. Can you please read section 6 [1] of CSS 
transforms. This is what you will read:

   | Specifying a value other than none for the
   | transform property establishes a new local
   | coordinate system at the element that it is
   | applied to.

The is similar to where a value other than visible for 'overflow' 
establishes a block formatting context [2]. Section 6 also has as follows:

   | The mapping from where the element would have
   | rendered into that local coordinate system is
   | given by the element’s transformation matrix.

The 'transformation matrix' is computed from the values of the transform 
and transform-origin properties. Furthermore, section 6 has a follows:

   | That is, elements establish their local coordinate
   | system within the coordinate system of their parent.

So each value other than none for the transform property establishes a 
new local coordinate system. The order in which transforms appear does 
not effect the transformation matrix but it does effect where the said 
element *appears* to be positioned globally. Please take note of the 
last part of example 4.

   | Note that an identical rendering can be obtained
   | by nesting elements with the equivalent transforms:

   | <div style="transform: translate(80px, 80px)">
   |   <div style="transform: scale(1.5, 1.5)">
   |     <div style="transform: rotate(45deg)"></div>
   |   </div>
   | </div>


> Say I have an element {top: 0px, left: 0px}, which I want
> to:
>   * move by 500px in x and 200px in y
>   * rotate by 25 degrees; and
>   * scale by 1.2 in x and 1.1 in y
>
> Regardless of the order in which I apply these operations, the element is
> always *locally* moved, rotated and scaled - that is, according to the
> element's local coordinate system (which changes with respect to the global
> coordinate system) the operations are a translate(500px, 200px), a
> rotate(25deg), and a scale(1.2, 1.1) regardless of the order in which
> they're applied.

What if each transform function is done by a chain of nested children?

  | That is, elements establish their local coordinate
  | system within the coordinate system of their parent.

> Of course, globally, it's a different story. Mostly the element is
> *not* translated
> globally by 500px, 200px, is *not* rotated by 25 degrees, or is *not* scaled
> in x and y by 1.2 and 1.1 respectively. For example:
> rotate(25deg) scale(1.2, 1.1) translate(500px, 200px)
> Globally, this is rotated by about 27 degrees. It's also significantly
> skewed, and it's translated in both x and y by about 450px.

No it is not. It is translated in x by 500px and is translated in y by 
200px. It is *not* skewed. Each corner is 90deg.

  Why are you concerned about it's global position?

> However, there is one ordering for which the local transformations produce
> matching global transformations:
> translate(500px, 200px) scale(1.2, 1.1) rotate(25deg)
> Globally, this is at position (500px, 200px) (well almost. Technically the
> origin has moved by this much). It's scaled by 1.2 in x and 1.1 in y, and
> it's rotated against the global x and y coordinate system by 25 degrees.

Does the same apply if I have transform-origin: 0% 0% or 
transform-origin: 100% 100%? Does the same apply if the parent has 
rotateY(60deg)?

> This ordering is clearly special, and clearly has strong advantages for the
> purposes of individual rotate, translate and scale properties - the result
> of setting these properties will always match across a global and a local
> coordinate system. Essentially, we want people to be able to specify:
>
> {
>    translation: 500px 200px;
>    rotation: 25deg;
>    scale: 1.2 1.1;
> }
>
> and have it Just Work.

And this is the only time that it appears like it has be skewed. Again 
why are you concerned about it's global position?

If I did a few transforms for a few ancestors with their own local 
coordinate system, in theory, you may not have anything to measure 
against some global position since the said element may be outside the 
veiwport.

>> I think what you meant to say is (correct me if I am wrong) that authors
>> most likely just will use one of the transform properties: Either rotate,
>> or translate, or scale or transform. And therefore you just want to have a
>> sane fallback if an author uses them in combination.
>>
>
> That isn't what we are trying to say. We want beginner authors to be able
> to naively specify translations, rotations and scales as if they were
> global, and to have them do what they almost certainly wanted them to; but
> we want more advanced authors to be able to use the transform property and
> control the ordering of transform components as well.

There is no global position. It's only due to nativity that one assumes 
that something has a global position. In my early days of using 
transforms, I rotated something before translating it. In my early days 
of using transforms, I didn't realise that the order was important.

So what should happen if I have the below styles in this order? Do I 
have it translating first or do I have it rotating first?

{
   rotation: 45deg;
   translation: 100px 100px;
}



> A handy bonus is that having separate translation: rotation: and scale:
> properties means it's easy to animate these channels independently of each
> other, without resorting to additive animation.
>
> Cheers,
>      -Shane

You can already do that in some respects. The below code works as expected.

@keyframes pframe1 {
   from  { transform: translateZ(-4000px) translateX(-1000px) 
translateY(1400px) ; }
   20%  { transform: translateZ(-400px);  }
   30%  { transform: rotateY(-0deg); }
   40%  { transform: rotateY(-60deg); }
   55%  { transform: translateY(1400px) rotateY(-180deg); }
   to   { transform: translateZ(500px) translateX(-1000px) 
translateY(1400px) rotateY(-180deg); }
}


1. http://dev.w3.org/csswg/css-transforms/#transform-rendering
2. http://www.w3.org/TR/2011/REC-CSS2-20110607/visuren.html#block-formatting


Alan
Received on Wednesday, 16 July 2014 12:21:26 UTC

This archive was generated by hypermail 2.3.1 : Monday, 2 May 2016 14:39:23 UTC