Implement CSS animation-composition
Categories
(Core :: CSS Parsing and Computation, enhancement, P3)
Tracking
()
Tracking | Status | |
---|---|---|
firefox104 | --- | fixed |
People
(Reporter: hiro, Assigned: boris)
References
(Blocks 3 open bugs, )
Details
(Keywords: dev-doc-complete)
Attachments
(3 files)
No description provided.
Updated•8 years ago
|
Comment 1•2 years ago
|
||
Just received notice that Webkit will be looking to make this functionality available in H1 2022.
Updated•2 years ago
|
Assignee | ||
Comment 2•2 years ago
|
||
Updated•2 years ago
|
Updated•2 years ago
|
Assignee | ||
Comment 3•2 years ago
|
||
Let nsAnimationManager takes animation-composition into account.
Note: This doesn't support animation-composition on each keyframes.
Assignee | ||
Comment 4•2 years ago
|
||
So we can use animation-composition in keyframes.
Assignee | ||
Updated•2 years ago
|
Pushed by bchiou@mozilla.com: https://hg.mozilla.org/integration/autoland/rev/9748d3bdef15 Part 1: Implement CSS animation-composition longhand in style system. r=emilio https://hg.mozilla.org/integration/autoland/rev/df1148c8baf0 Part 2: Hook animation-composition to CSS animations. r=emilio https://hg.mozilla.org/integration/autoland/rev/f745c54f8526 Part 3: Support animation-composition in keyframe at rules. r=emilio
Comment 6•2 years ago
|
||
bugherder |
https://hg.mozilla.org/mozilla-central/rev/9748d3bdef15
https://hg.mozilla.org/mozilla-central/rev/df1148c8baf0
https://hg.mozilla.org/mozilla-central/rev/f745c54f8526
Hello, I am documenting this new 'animation-composition' property and finding it a little difficult to come up with suitable examples to demo this feature. (I am using Firefox 104.0b9 (64-bit)). I am looking for the following information and I'd really appreciate any help.
- Any real-world examples, real use cases where a web developer would want to use 'animation-composition' on a property across multiple animation keyframes?
- What are the likely properties for which the composite effect of add and accumulate can be used/will be useful?
- What is the difference between the values 'add' and 'accumulate' and what properties can I visually show the difference in their meanings?
- The spec says:
When specified in a keyframe, animation-composition defines the composite operation to use for each property specified in that keyframe until the next keyframe specifying each property.
Does this mean from their example that since @keyframes heartbeat has multiple values of scale, there would be a composite scale effect if the animation on the .heartbeat class styling is animation: heartbeat 0.3s 2s accumulate; ? I do not see any visual difference on testing.
5. I tried the examples from the spec here https://codepen.io/dipikabh/pen/xxWQzwa and here https://codepen.io/dipikabh/pen/NWYEYdz. I cannot make out the difference between the three - 'add', 'replace', or 'accumulate'.
Thanks,
Dipika
Assignee | ||
Comment 8•2 years ago
•
|
||
Hi, Dipika,
Thanks for documenting this CSS property. I tried my best to answer the questions below.
- Any real-world examples, real use cases where a web developer would want to use 'animation-composition' on a property across multiple animation keyframes?
Basically, I'm not sure if I'm a suitable person to answer this. However, if a web developer wants to combine the animation effect with its underlying value, animation-composition
is the declarative way to define this, just like what we do for KeyframeEffect.composite
. Perhaps you could check the answers below.
- What are the likely properties for which the composite effect of add and accumulate can be used/will be useful?
https://developer.mozilla.org/en-US/docs/Web/API/KeyframeEffect/composite provide an example by using filter
, so perhaps we could use the same property in the MDN for animation-composition
. Besides, I think transform
property is also a good example to demo this. See the example in the 3rd answer.
- What is the difference between the values 'add' and 'accumulate' and what properties can I visually show the difference in their meanings?
First, the definition is in web animations spec: https://drafts.csswg.org/web-animations-1/#effect-composition, and in https://drafts.csswg.org/css-values-4/#combining-values
a) add
: The effect value is added to the underlying value. For animation types where the addition operation is defined such that it is not commutative, the order of the operands is underlying value + effect value.
b) accumulate
: The effect value is accumulated onto the underlying value. For animation types where the accumulation operation is defined such that it is not commutative, the order of the operands is underlying value followed by effect value.
It's a little bit tricky to see the difference between add
and accumulate
. transform
property is a good example to see the difference.
See related wpt: https://searchfox.org/mozilla-central/source/testing/web-platform/tests/css/css-transforms/animation/transform-translate-composition.html
e.g.
@keyframes anim {
from { transform: translateX(100px); }
to { ... }
}
#target {
transform: translateX(100px) rotate(90deg);
}
The underlying value is translateX(100px)
. So if we are using add
, the "from" animation value is transform: translateX(100px) rotate(90deg) translateX(100px)
. If we are using accumulate
, the "from" animation value is transform: translate(200px) rotate(90deg)
.
I also wrote an example in the 5th answer, so you can check the visual difference.
- The spec says:
When specified in a keyframe, animation-composition defines the composite operation to use for each property specified in that keyframe until the next keyframe specifying each property.
Does this mean from their example that since @keyframes heartbeat has multiple values of scale, there would be a composite scale effect if the animation on the .heartbeat class styling is animation: heartbeat 0.3s 2s accumulate; ? I do not see any visual difference on testing.
This means the keyframe-specific composite: https://drafts.csswg.org/web-animations-1/#keyframe-specific-composite-operation.
The example doesn't do this. I think the spec words mean something like this:
@keyframes anim {
from { transform: translateX(100px); animation-composition: add; } // we define animation-composition inside @keyframes rule.
to { transform: translateX(200px); }
}
#target {
animation: anim 1s linear;
animation-composition: accumulate;
trasnform: translateX(100px) rotate(90deg);
}
So the first keyframe, we apply animation-composition: add
, but the second keyframe, we don't define animation-composition
the this keyframe, so we use the animation-composition
of this element, i.e. accumulate
here. (I didn't write an example for this, but you can update my example in codepen to see the difference after adding animation-composition
in a keyframe.)
- I tried the examples from the spec here https://codepen.io/dipikabh/pen/xxWQzwa and here https://codepen.io/dipikabh/pen/NWYEYdz. I cannot make out the difference between the three - 'add', 'replace', or 'accumulate'.
I notice the preference is off by default, so first we have to enable the preference in Nightly: layout.css.animation-composition.enabled
. Sorry about this. And I'm not sure these example are good to demo the visual difference between replace
and accumulate
. I saw a very minor difference between replace
and add
in these two cases.
However, I believe this cannot convince you, so I wrote another example for your reference: https://codepen.io/BorisChiou/pen/XWEyxXE
Thanks. :)
Thank you so so much, Boris! I really appreciate this info. Your examples have helped clarify a lot of concepts. The comments in WPT are useful for documentation purposes; thanks for sharing that! I do have a few follow-up questions:
-
You mentioned that "the preference is off by default." Is that intended? I thought this feature would be available by default in 104 version. If it's behind a preference setting that needs to be turned true, I will need to document that.
-
In your example explanation in 3 in the previous comment:
The underlying value is translateX(100px). So if we are using add, the "from" animation value is transform: translateX(100px) rotate(90deg) translateX(100px). If we are using accumulate, the "from" animation value is transform: translate(200px) rotate(90deg).
Did you mean that the underlying value is transform: translateX(100px) rotate(90deg)
?
-
In your keyframe-specific composite example, because there is no animation-composition in the second keyframe and you said that it will take 'accumulate' from the element, so will that be interpreted as:
to { transform: translateX(200px); animation-composition: accumulate;}
?
I guess from the link you've shared https://drafts.csswg.org/web-animations-1/#keyframe-specific-composite-operation it seems to me thatfrom { transform: translateX(200px) rotate(90deg); animation-composition: add;}
, which has multiple properties, would mean that the composite operation is applied to translate and rotate. -
So in case of keyframe-specific composite, basically the animation is getting composite operation defined at the keyframe level instead of at the selector/element level?
-
Some questions on your codepen example (thanks a ton for putting this together!!):
- "replace" and "accumulate" seem to be working as expected - effect value replaces the underlying value so "from" in "replace" is
transform: translateX(100px)
and accumulate combines the effect so "from" in "accumulate" istransform: translateX(150px) rotate(90deg)
. - However, in the "add" case, "from" would be
transform: translateX(50px) rotate(90deg) translateX(100px)
. The second green box is rotated alright and seems to have moved 50px but it is moving from top to down - I was expecting it to move another 100px horizontally and animate horizontal move "to" 200px. Could you explain theanimation-composition: add;
behavior here?
Thanks a lot,
Dipika
(To make this less cumbersome and reduce the back-and-forth, would you mind connecting on Slack? I am in Germany, so 9 hours ahead.)
Comment 10•2 years ago
|
||
Oh! I think I get the "add" behavior in your codepen now. The move is happening top to down because the green box has rotated. So translateX behaves like translateY after the rotate. Is that correct?
Assignee | ||
Comment 11•2 years ago
|
||
(In reply to Dipika from comment #9)
- You mentioned that "the preference is off by default." Is that intended? I thought this feature would be available by default in 104 version. If it's behind a preference setting that needs to be turned true, I will need to document that.
Don't worry about this now. I am enabling it on Nightly (105): https://bugzilla.mozilla.org/show_bug.cgi?id=1785329. This bug just implemented this property, but the preference is still default by off on Nightly. So perhaps you can document that the feature is enabled by default on since Nightly 105. However it is still not ready to be enabled on beta and release version. animation-composition
longhand is enabled only on Nightly.
- In your example explanation in 3 in the previous comment:
The underlying value is translateX(100px). So if we are using add, the "from" animation value is transform: translateX(100px) rotate(90deg) translateX(100px). If we are using accumulate, the "from" animation value is transform: translate(200px) rotate(90deg).
Did you mean that the underlying value is
transform: translateX(100px) rotate(90deg)
?
Oh yes. Sorry for the typo. I updated my example again and again when writing the the answer so I forgot to double-check it. Yes, the underlying value should be transform: translateX(100px) rotate(90deg)
.
- In your keyframe-specific composite example, because there is no animation-composition in the second keyframe and you said that it will take 'accumulate' from the element, so will that be interpreted as:
to { transform: translateX(200px); animation-composition: accumulate;}
?
Yes.
I guess from the link you've shared https://drafts.csswg.org/web-animations-1/#keyframe-specific-composite-operation it seems to me that
from { transform: translateX(200px) rotate(90deg); animation-composition: add;}
, which has multiple properties, would mean that the composite operation is applied to translate and rotate.
I'm a little bit confused about the question, so I try to list some possible answers here:
- Basically,
animation-composition
is not animatable (spec link), which means we don't have to worry about this in the keyframe. In other words, it is not relatedtransform
, and you will not see any animations onanimation-composition
. Basically, you can treatanimation-composition
as an extra attribute for this Keyframe so we can know this Keyframe usesadd
, instead ofaccumulate
, in this example. - Basically, each Keyframe has a composite operation type, i.e.
replace
,add
, oraccumulate
. (note: you can use getKeyframes() to dump all the attributes for a specific Keyframe), so I think we can say, the composite operation is applied to "this keyframe". (i.e. All properties in this Keyframe).
- So in case of keyframe-specific composite, basically the animation is getting composite operation defined at the keyframe level instead of at the selector/element level?
The answer should be yes. the composite operation defined at the Keyframe has the higher priority.
An animation has a list of Keyframes, and each Keyframe has a composite operation (note: the DOM dictionary of Keyframe), so basically, when we see an animation for this element, we build the list of Keyframes for this animation. And when building a Keyframe, we choose the composite operation for this keyframe from 1) the keyframe-specific composite, 2) the animation-composition
property for this element.
- Some questions on your codepen example (thanks a ton for putting this together!!):
- "replace" and "accumulate" seem to be working as expected - effect value replaces the underlying value so "from" in "replace" is
transform: translateX(100px)
and accumulate combines the effect so "from" in "accumulate" istransform: translateX(150px) rotate(90deg)
.- However, in the "add" case, "from" would be
transform: translateX(50px) rotate(90deg) translateX(100px)
. The second green box is rotated alright and seems to have moved 50px but it is moving from top to down - I was expecting it to move another 100px horizontally and animate horizontal move "to" 200px. Could you explain theanimation-composition: add;
behavior here?
For add
, We can remove animation-composition and change @keyframe rules to get an equivalent animation, like this:
@keyframes anim2 {
from {transform: translateX(50px) rotate(90deg) translateX(100px);}
to {transform: translateX(50px) rotate(90deg) translateX(200px);}
}
#target {
width: 50px;
height: 100px;
background: green;
border-radius: 10px;
animation: anim2 2s linear infinite;
}
So Yes, from top to down is correct. Because it moves after it rotated 90deg. (All the transform operations can be converted into a matrix!)
You could check the conversion for the transform matrix: https://drafts.csswg.org/css-transforms/#mathematical-description. And a simple way is to write the the matrix of each operation, and do the matrix multiplication on them.
An easy way to know is: we rotate 90deg, so the x-axis of this element also rotates 90deg, and then translateX(...)
becomes from top to down. (Another try to see what happens: change from rotate(90deg)
to rotate(45deg)
, and its x-axis rotates 45deg now.) In conclusion, we cannot use the global x-axis for transform. :)
Anyway, it's also complicated to me. That's why transform
property is a good example for animation-composition
because the matrix multiplication is not commutative.
(To make this less cumbersome and reduce the back-and-forth, would you mind connecting on Slack? I am in Germany, so 9 hours ahead.)
Sure. My slack account is also boris
(in Portland, Oregon, USA). Leaving comments here is also a good way because I have more time to think about the questions.
Assignee | ||
Comment 12•2 years ago
•
|
||
(In reply to Dipika from comment #10)
Oh! I think I get the "add" behavior in your codepen now. The move is happening top to down because the green box has rotated. So translateX behaves like translateY after the rotate. Is that correct?
Yes! We can not use global x-axis or y-axis to see the result. This is a matrix multiplication.
Comment 13•2 years ago
|
||
Thank you so much, Boris! All this has been extremely helpful, especially your clarifications to my queries.
I have now documented the animation-composition
property. I am using your example in the doc :-). I have not elaborated on the keyframe-specific composite case in the doc for now, to first get the basics right.
I'd appreciate of you could take a look a the doc and point out if you see any glaring technical inaccuracies: https://github.com/mdn/content/pull/19848
Assignee | ||
Comment 14•2 years ago
|
||
(In reply to Dipika from comment #13)
Thank you so much, Boris! All this has been extremely helpful, especially your clarifications to my queries.
I have now documented the
animation-composition
property. I am using your example in the doc :-). I have not elaborated on the keyframe-specific composite case in the doc for now, to first get the basics right.I'd appreciate of you could take a look a the doc and point out if you see any glaring technical inaccuracies: https://github.com/mdn/content/pull/19848
I notice there are some comment there already, so I will take a look later once you addressed those comments. :)
Comment 15•2 years ago
|
||
The documentation for animation-composition
is now available: https://developer.mozilla.org/en-US/docs/Web/CSS/animation-composition.
Issue tracker that was used for this work: https://github.com/mdn/content/issues/18771
Thanks Boris for all your help with this feature.
Updated•1 year ago
|
Description
•