W3C home > Mailing lists > Public > www-style@w3.org > March 2011

Re: [css3-2d-transforms] "longhand" for the transform stack

From: Dean Jackson <dino@apple.com>
Date: Wed, 30 Mar 2011 05:43:11 +1100
Cc: www-style@w3.org
Message-id: <2D420C8F-B4EB-4C3E-B03E-9FC34483F32F@apple.com>
To: Aaron Gustafson <aaron@easy-designs.net>
Up front, sorry if I'm sounding difficult on this. I'm really not trying to be. My intent is to explain the current situation and try to come up with something that works. You're raising valid concerns about the difficult for authors.

On 30/03/2011, at 3:43 AM, Aaron Gustafson wrote:

> 
> 
> On Mon, Mar 28, 2011 at 6:43 PM, Dean Jackson <dino@apple.com> wrote:
> 
> On 29/03/2011, at 8:49 AM, Aaron Gustafson wrote:
>> On Fri, Mar 25, 2011 at 8:17 PM, Dean Jackson <dino@apple.com> wrote:
>> 
>> I think it's too late to change what 'transform' means. Note that this has existed in SVG for more than 10 years now.
>> 
>> 
>> I understand where you're coming from, but I'm approaching this from an author's standpoint, not from that of an implementor or a spec writer. If more web designers wrote SVG by hand (and had been doing so for the last 5-10 years), it might not be a problem, but the fact is that, by and large, they haven't. And speaking as someone who is frequently called on to train folks on these new techniques and technologies, the truth is that the current transform setup isn't easy to grasp.
> 
> Understood. My point was that we can't make a change now that would break existing content in SVG or CSS.
> 
> 
> SVG I understand. On the CSS front, it's not a final spec yet, so I'm not really all that concerned about "breaking existing content" because all current implementations should be using vendor prefixes, meaning they're experimental and subject to change. That's the whole point, right?

Yes and no. It's true we can change things, but one of the primary goals of CSS transforms is to be compatible with SVG transforms. There are already slight incompatibilities (regarding origin). The idea is that you should be able to take an SVG transform and paste it into CSS.

>  
>> Of course it is. As I said, I'm spitballing here. I think this is a discussion we need to have and there are likely to be a number of harebrained ideas that come out of the discussion, but if we have this discussion we can (hopefully) get to a place where the spec meets the needs of authors as well as implementors. 
> 
> A thought I had after I replied was that it *might* be possible to make transform take a list of lists, sort of like background-image.
> 
> eg:
> 
> transform: scale(2), rotate(10deg);
> 
> which would mean apply a scale then a rotate. Then have a magic keyword that means to use whatever the current value for the functions in that spot are.
> 
> transform: same, rotate(20deg);
> 
> That would keep the scale the same but add another 10 degrees of rotation.
> 
> The problem is that it means there is a difference between space separation and comma separation. Is this easy to work out?
> 
> transform: scale(2) rotate(10deg), rotate(-10deg) translate(10px, 3px) scale(3), translate(-40px, -20px);
> 
> Probably yes, because it would actually be the same as without commas (other than the necessary ones within functions). Now suppose we move to this:
> 
> transform: same, rotate(50deg), same;
> 
> I still think the added complexity isn't worth it. I've not seen many complaints over confusion of ordering from authors. The most common request is exactly what you're asking for, a way to modify just a particular parameter, but they usually understand the issue with ordering.
> 
> 
> I think it's an interesting idea, but it seems like it could get really confusing really quickly.

Yes, that's the problem. Even with the simplified proposal below, things are confusing (see below).

> In terms of complaints from authors, I'm starting to see them as more people have begun to dabble. People familiar with SVG and transformation matrices (e,g, animators and the like) probably won't have any problems picking this up. Your average web designer or developer, however, is likely to be overwhelmed. I think there's a balance to be struck between a the power of a technology and an author's ability to easily comprehend that technology. If we don't find that balance, adoption may be considerably slower than many of us would like.
>  
>>  I'm not debating the power and flexibility of the current transform proposal, but I am trying to figure out if there's a better/alternate way to provide access to the power of transform that is easier for authors to wrap their heads around and that serves their actual needs (rather than hypothetical ones). I find the current implementation lacking in that area.
> 
> I'd be interested to hear the use case? As Simon pointed out in another reply, the way most authors address this issue is by nesting elements.
> 
> <div style="transform: scale(2)">
>   <div style="transform: rotate(10deg)">
>     <img src="whatever.png">
>   </div>
> </div>
> 
> That way you can tweak rotation and scale independently quite easily. In fact you generally need to do this if you want to animate each at different rates.
> 
> 
> I guess it depends on the level of purist you want to be. Sure, you could add the extra markup to accomplish this, but should you have to? More on this below.

You don't have to. I was just saying that if you really want to be able to manipulate the functions individually, then you can add extra markup. If you're happy with a list of transform functions, then you only need a single element.


>> It seems the main inconvenience from your original post is that you have to duplicate the entire list of transformation functions each time. Is that really a big deal?
>> 
>> 
>> Yes, actually. Here are the problems/reasons for my post to begin with any why I think the current syntax and implementations are not author-friendly:
>> 
>> 1) It's not intuitive - many designers and developers have a hard time grasping that there is only the transform stack and that whenever you set a value for it with a more specific selector, all previously-applied transforms are dropped and there's no way around it. Having an alternate syntax for "simple" transforms could address that (e.g. setting rotation on an element would not need to interfere with scale set elsewhere).
> 
> I understand this, but the problem is that transforms don't really work this way. As an author, you need to decide the order of transform functions. If the specification decided one way, then there would be a bunch of people who wanted it another way.
> 
> 
> Agreed. Modified consensus would be the only way to progress on the spec, and that's probably too much to hope for.

I should have also added that dictating an order can be even more confusing for authors (again, see below).

> 
>  
> It might be possible to add three new properties that are applied before the regular transform property. 'transform-scale' '-rotate' '-translate'. This would probably address your need in the simplest manner, and would be easy to implement. We'd define the order.
> 
> 
> I think having "longhand" versions of the properties would make a lot of sense, but (like Kenny), I'd probably argue for applying them *after* the translate stack. Again, more in a second.

So here's the problem with dictating an order: that it can make anything after the first function less obvious. Suppose we decided on translate -> scale -> rotate? You want to make something twice as big: multiply scale by 2. That works fine. Now imagine you want to move it towards the right by its width. Do you translate it by width or 2*width? Now add in a rotation of 45deg. Translating by negative Y will move it down the page, but what if I wanted to move it down in the direction it is pointing? The problem is that it looks like all these things are independent, but they are not. You can't reliably modify one function unless you know what the others are. I expect this will be very confusing to authors. At least when there is a single property it is clear that everything applies.


>  
>> 2) It leads to source bloat - this setup does not help us keep with the DRY principle (don't repeat yourself), which leads to larger files and longer downloads. Having an alternate syntax would help us keep our files smaller.
> 
> It's true that source files are bigger, but since you're using a very similar pattern in each instance I doubt it makes a big difference in (gzipped) download.
> 
> 
> Possibly. But maintainability is also an issue with so much potential repetition.
>  
>> 3) Tweaking an element's style.transform property via JavaScript is unnecessarily complex (as the current state is pretty much always exposed as a matrix and it is difficult to suss out the current state in order to make adjustments).
> 
> Yeah, that's ugly. Your only option on the reading end is to look at the property value and parse it yourself :( Reading is definitely hard, but writing is a little easier. There is an API to, say, scale a matrix by 3. That only helps if you are adding to what is there.
> 
> 
> Where can we have a discussion about address that? We need a better API capable of giving us information back about the current state of things (like current rotation, scale, etc.).

This is another problem. There isn't really a concept of current rotation, scale, etc. You can decompose the final matrix into a list of components, but it isn't necessarily what you put in (it's just a particular input that would give the visible output).

For example, rotate(0) and rotate(360deg). Decomposing them gives the same value.

Let's walk through two use cases.

1. You want to rotate the current element *by* 45deg. You can do that today with the matrix value.

2. You want to *set* the current rotation to 45deg. This is trickier. Suppose we did provide an API to decompose a matrix. Ignoring the N == N+360 problem, imagine the value returned for rotation is 25deg. You want to set that to 45deg. Except you still run into the problem above, where changing this value will affect everything afterwards. It will work ok if the only function on the element is a rotation.

The other option would be to provide a better API to work with the original transform list. That way, as an author you should be aware of the list of functions you provided. 

myElement.style.transform.rotation[0] = 45; // make the first rotation function 45deg

You haven't avoided the problem, but it might be ok in some situations. It depends on how you've authored the content.

>  
>> Being able to _easily_ determine properties such as the current rotation angle would be a godsend.
>> 
>> 4) JavaScript-based class-swapping produces the smoothest transition effects, but (again) requires a lot of extra CSS code for anything more complex than a stack of one or two transforms. If we had longhand properties, we'd be able to streamline the classes used for JavaScript-triggered animations.
> 
> What do you think about adding the extra properties above?
>  
> 
> Ok, so I think the extra properties are great (but I think there'd be more than three... you'd want one for each transform function).

Including all the 3d functions? That's a lot of properties (not such a big issue) with a really difficult choice for ordering (a big issue). Should the 3d translates come before the 2d scales?

> I think the question becomes: should they be applied before or after? Before allows you to keep the primary transform stack as the primary mechanism for element manipulation. After allows you to make singular augmentations to an existing stack. Which is more likely to be useful? I'm not sure I know the answer to that.

Applying them after will make the ordering problem worse. Suppose I want to move something across the page by 100px (transform-translate: 100px, 0px) and there is an existing transform that is scale(0.01).

Applying before will move the element, then scale it (to make it small). At least I did move the element to where I wanted though.

Applying after means that the translate will only move 1px (0.01 * 100), and still make the element small. You really need to know what's come before you in the transformation list.

Dean

> 
> One thing I do know, and this goes to your earlier comment about timing the transition of two transform function separately, by allowing us to separate transforms out from the stack, it would enable us to animate each transform function independently without requiring additional markup:
> 
> img:hover {
>   transition: transform-scale 3s, transform-rotate 5s;
> }
> 
> Of course the question then becomes: Would setting the transition timing for a "longhand" transform property affect the transition of that function in a transform stack? I'm guessing the answer to that is probably "no," but I thought I'd ask.
> 
> 
> On Mon, Mar 28, 2011 at 7:53 PM, Kang-Hao (Kenny) Lu <kennyluck@w3.org> wrote:
>  
> In light of this, what about a new property called "also-transform",
> which cascades separately and happens after "transform"? This idea can
> be extended to "also-background" and is sort of a solution to ISSUE-177,
> but as this looks ugly, I wouldn't say I really like this solution.
> 
> I think this might be a use case that the CSS Mixin module (if we create
> it) might want to address. A less uglier might look like "+transfrom:
> rotate(40deg)".
> 
> 
> It's an interesting idea, for sure.
> 
> Cheers,
> 
> Aaron
> 
> ----
> Aaron Gustafson
> Principal
> Easy! Designs, LLC
> +1 877 EASY 313 x101
> aaron@easy-designs.net
> @aarongustafson
> 
Received on Tuesday, 29 March 2011 18:43:49 GMT

This archive was generated by hypermail 2.3.1 : Tuesday, 26 March 2013 17:20:38 GMT