3 Ways to Use Independent Transform Properties
I figure there are three main ways we can break out the individual transform functions (such as
scale) from the
transform property without a library. The ability to set a new
rotate without it affecting a previously set
scale, for example, has long been desired by web developers. We’ll take a look at the pros and cons of each approach.
These pros and cons will be centered around each approach’s ability to support the following:
- Can we do any number of functions (multiple
- Can we specify the order (e.g.
translategives a different end result than
- Can they be transitioned (via
- Can they be animated (via CSS Animations/
keyframesor the Web Animations API)?
To see why the first two points matter, play around with the following pen by reordering the transform functions and adding more.
#1 Actual Independent Properties
Defined in the in-progress CSS Transforms Level 2 specification (and in Chrome behind the Experimental Web Platform Features flag),
rotate become their own properties. They can be handled individually, and therefore each can be animated and transitioned separately, too.
You can transition and animate each individually as well, so for example you can specify different easings and durations for your
translate than your
- Straightforward syntax
- Can be transitioned and animated independently
- Skew function is not represented
- Can only do one function per axis for each property… if you need to do multiple transformations you must use the
- Always applied in the order:
scale… if you need a different order you must go back to the
- Only in Blink browsers with flag enabled as of this writing.
To be fair, the order that these individual properties are applied is a very common order for people to use, and multiple transformations are rarer, too. They still are a key difference with the
transform property which gives a lot more power.
#2 Custom Properties
I discovered the possibilities of mixing custom properties with the
transform property earlier this year, and well… I’m still excited about them. I’ll summarize the process here, but please check out the original article for more details.
The idea here is that we set up the standard
transform property as we always have with every transformation we want to eventually apply using custom properties (which are supported in Firefox, Edge, Safari, Chrome, and Opera).
Now we can specify the order of our transformations, and we can do as many transformations as we want, since we are using our old friend
We can even do transitions on the
transform and any changes to one of the custom properties will trigger the transition. So in our example we could set a
transition: transform 200ms ease-in-out in our rule and when the
changed class is added we will smoothly move to our new location. The caveat here is that it is specifically a transition on the single
transform property so your translation, for example, cannot have a different duration, easing, or delay than your scale.
Here is an example showing this approach on a button with multiple states. It also shows the first approach if you are in an enabled browser so you can compare them.
- Any number of transforms allowed
- We can use any order we want
- Supported anywhere custom properties are (Apple, Microsoft, Mozilla, Google, Opera all have them)
- More verbose
- Need to account for all potential transformations up front
- Keyframe animations and Web Animations API won’t work as intended
About that last bullet point…
As I discussed in an article about animating Single Div art, the Custom Properties Level 1 specification does not introduce mechanisms to specify a syntax or value type for a given custom property. Therefore, the following will either do nothing or flip states at the 50% mark in the animation:
Houdini + Custom Properties
chrome://flags) and visiting this Houdini playground (and its references) to get an idea of how it works and what is possible.
--translate-x custom property as a
length value and our
--rotate as an angle. With that small amount of extra information, the browser now has what it needs to do the keyframe animation as we would want.
#3 Composite/Add Animations
Now that you have a taste for the future and are okay with living in dev browsers and/or enabled flags, I want to talk about an old favorite of mine: the Web Animations API. This approach is not like the others and has a smaller use case, but it is still a way to work with transform functions independently.
There are times you have multiple animations going on for the same element — maybe one is changing the opacity, while the other is moving it across the screen. They can have different durations, easings, etc. In the Web Animations API you can achieve this with the following:
Let’s change that to be two animations with two different
Since those are created and running at the same time, only the rotation is applied because they are modifying the same property and the first animation’s requested changes are effectively ignored.
The Web Animations specification introduces the
composite operation (and the related
iterationComposite). The default
replace and has the behavior we have had for years now where an animated property’s value simply replaces any previously set value — either from a rule set or another animation.
add value is where things change from the previous norms. Taking our example above with the two
transform animations, we can modify the second to use the new
composite value of
Now both animations will be seen as the browser on the fly figures out the appropriate transformation at a given point in the animation’s timeline accounting for both transformations. In our examples, the easing is
'linear' by default, so we can break out what the effective
transform is at any given point. Such as:
translate(10px) rotate(30deg)(halfway through first animation, 1/3 through second)
translate(20px) rotate(60deg)(end of first, 2/3 through second)
translate(20px) rotate(90deg)(end of second)
The Web Animations API is in Firefox, Chrome, and Opera already. However, this piece of functionality is currently only in Firefox Nightly. You can see it in action in that browser (Nightly is v58 as of this writing) in the following samples. If you view them in another browser you will see the typical
replace behavior instead.
There is also an ongoing discussion in the CSS Working Group about adding this functionality to CSS, even beyond the context of animations.
- Allowed in animations and transitions started by the Web Animations API
- Any number of transformations are allowed
- Order can be controlled, but depends on which animations have the
- Still working on spec
- Only in Firefox Nightly currently
- Only defined in Web Animations API (at the moment)
- Less relevant for the non-animated use cases for separating transformations
Are there more?
There surely are other ways to accomplish this (such as doing a lot of calculations in a
requestAnimationFrame or specifying all the different combinations possible in CSS), but these three represent the solutions with the least overhead and have the future in mind. It bears repeating that not everything discussed works today and none of these are in every browser that is available.
It doesn’t really bear repeating, though; that’s just how the web works. There is nothing wrong with looking to the future, and seeing how emerging technology is solving the problems of today.