- From: Tab Atkins Jr. <jackalmage@gmail.com>
- Date: Thu, 17 Jul 2014 09:47:43 -0700
- To: www-style list <www-style@w3.org>
[This is a restart of the previous thread, as requested by the WG, because the old one was long enough to make it confusing to tell what precisely was being proposed.] Earlier I saw a Twitter thread started by Lea <https://twitter.com/LeaVerou/status/487350702386479105> about how she commonly accidentally types the name of the transform she wants as the property (like "rotate: 45deg;") and then has to go back and correct it afterwards. Several other devs chimed in that they do this as well, and I know that I've done it a few times (especially when using SVG - I use "transform='translate(...)'" so often that I commonly try to name the attribute "translate" first). Common mistakes like this often translate to an unexpectedly clumsy design, so I got to thinking about fixing this. After some discussion on the WG, a basic design emerged that turned out to have other important benefits as well. I propose we add the following three properties to the Transforms spec: * translate: <length>{1,3} - specifies a translation in the X, Y, and Z axises, respectively. Missing values default to 0. * rotate: <angle> <number>{3}? <'transform-origin'>? - specifies a rotation along a given axis from a given origin. An omitted axis defaults to 0,0,1; an omitted origin defaults to 'transform-origin's initial value. * scale: <number>{1,3} <'transform-origin'>? - specifies a scale in the X, Y, and Z axises, respectively, from a given origin. Missing values default to 1; an omitted origin default to 'transform-origin's initial value. The properties are implemented as if they were turned into their equivalent transform functions, then prepended to the 'transform' property in TRS order (with the origins applied as pre/post translates around each one). Thus, the 'perspective' property affects these properties, and the 'transform' property itself simply applies after these properties. Adding these properties has a number of benefits: * These three transforms have the unique property that, when applied in the proper order, they look "independent". That is, a translate always moves the element left/right and top/down the specified amount, rather than moving them along some rotated axis or by some multiplier of the distance you specified. A scale always scales the element along its width/height, rather than doing less predictable squishing along some rotated axis. Other transform functions, like skew(), do not have this property, and so are not being proposed as properties. * Authors no longer have to remember the ordering of these transform functions when they just want simple, "independent" effects. (And the correct ordering is frankly hard to understand - I think most people, if they're not careful, would describe them in TSR order, but that links the effects of scale and rotate in a weird way due to the math. Shane did this in the prior thread, for example.) * The three properties can be adjusted and animated independently, making a number of effects easier or even *possible* for the first time. For example, scaling an element on hover and rotating it on click currently requires you to write out a full 'transform' value with both scale() and rotate() functions on all four possible combinations of hover and click; with these properties, you could simply write a 'scale' property for :hover and a 'rotate' property for :active and everything works out. For another example, doing any transform to an element while a different type of transform is being animated on the element is currently impossible; it's trivial with these new properties. * A common authoring mistake (writing the desired transform as the name of the property) becomes correct behavior, at least for a common subset of properties. Some further discussion topics: * Since browsers treat 2d and 3d transforms differently, I assume we need to specify that, say, a 2-value 'translate' is equivalent to translate(), but 3-value is equivalent to translate3d(), even though we could technically always turn it into translate3d(), and similar with the other two properties. * It might be worthwhile to make scale and rotate into shorthands for their value, origin, and axis (for rotate). It seems reasonable to want these to cascade independently, so you can, for example, set a rotate on some axis and then adjust the rotation without having to repeat the axis each time. * TRS ordering is clearly correct when considering just these three properties, but is it correct when combining with 'transform'? That is, is TRSTr a logical ordering for authors? Since rotates and scales may have an effect on the additional transforms in the 'transform' property, it might be better to have the actual order be TTrRS, which I think ensures that *all four* properties can be thought of as "independent". For example, currently "el { rotate: 45deg; translate: 100px; }" does the "independent" thing - the element is moved 100px to the left and is rotated 45deg. But "el { rotate: 45deg; transform: translate(100px, 0px); }" doesn't - the element is instead moved approximately 70px left and down, and rotated 45deg. With my suggested ordering, the two would have the same effect. I don't *think* there are any unexpected effects here, but I'd have to think about what's expected if you do a "transform: scale(2, .5); rotate(45deg);". It might just be that in some cases you get a weird effect like this, but does the reordering minimize the weirdness? ~TJ
Received on Thursday, 17 July 2014 16:48:30 UTC