- From: Tab Atkins Jr. <jackalmage@gmail.com>
- Date: Mon, 5 Apr 2010 16:34:35 -0700
- To: www-style list <www-style@w3.org>
While I don't personally believe that Transitions and Animations will benefit from being fully merged, I do think that we need the ability to manipulate more than just the property that is changing during a transition. Simon Fraser put together an excellent example of a sliding box in a container; when you hovered the container, the box would slide from left to right (a transition on the "left" property), and would also wobble up and down (an animation manipulating the "top" property). Right now, you can't hook these two actions together. You have to specify something like this: @keyframes bounce { from { top: 0; } 25% { top: -20px; } 50% { top: 0; } 75% { top: 20px; } to { top: 0; } } .slider > .box { left: 0; transition: left 1s; } .slider:hover > .box { left: 400px; animation: bounce 1s; } This has several problems: 1. Even though, conceptually, you're wanting to say "when left changes, animate it and also bounce", the syntax as currently drafted doesn't indicate that. Instead, you have a "left" transition, and then separately, a bounce animation that happens to occur at the same time and have the same duration. 2. When you stop hovering, the "left" will still transition, but the bounce animation won't run again. To fix that you have to specify an animation on ".slider:not(:hover) > .box" as well, which is unintuitive and extraneous. This still doesn't work right, though, as the box will now bounce on page load (since the selector matches). You have to use javascript to get around this (to be precise, you have to set a class on the slider when you hover it for the first time, and qualify the reverse animation with that class). 3. This doesn't address any other conditions that could change the "left" value of .box. To do that, you have to set up additional animations, and reverse animations, for each separate one. This creates a combinatorial explosion (if you have 3 states that could change "left", you need to set up 6 animations, etc.) 4. Animations don't run again if you change from one state specifying the animation to another state specifying the same animation. To get it to run in reverse, you have to define a *second* keyframe that is exactly identical except with a different name, and use that for the reverse transition. If you have multiple states (see #3), you have to replicate the keyframe with a unique name for every possible transition. All of these are caused by the fact that you're trying to animate "top" when "left" changes, but the syntax doesn't allow you to actually *say* that. I propose a slight change to the syntax of transition-property to express this more properly. In addition to taking the name of a property, transition-property also takes a "play(<property name>, <keyframe name>)" function. This specifies a keyframe to run when the specified property changes. The example from the beginning of this email would then be: @keyframes bounce { from { top: 0; } 25% { top: -20px; } 50% { top: 0; } 75% { top: 20px; } to { top: 0; } } .slider > .box { left: 0; transition: left 1s, play(left, bounce) 1s; } .slider:hover > .box { left: 400px; } This now expresses the intention much more clearly (I am running the bounce animation when the left property changes), and thus makes the entire thing *actually work*. I don't need to jump through any hoops to run the animation when I stop hovering, and if any additional states could change the "left" value, the animation will run for them as well. Issues that aren't yet resolved (but I think are fairly easy): 1. What if my bounce animation happened to also manipulate "left"? I believe we can rely on the standard rule for animations, where the last specified animation wins whenever there is a conflict in what a value should be. A plain transition can then be thought of as an auto-created trivial keyframe manipulating the given property. 2. I believe that true animations automatically override transitions. This should apply equally to both plain transitions and keyframe transitions. I think this is the minimal syntax addition that expresses the display semantics we want. I also think this fully addresses the use-case I identified, that of manipulating multiple properties whenever a given property's value changes. ~TJ
Received on Monday, 5 April 2010 23:35:28 UTC