Status: ED Work Status: Exploring Shortname: css-animations-2 Level: 2 Group: csswg ED: https://drafts.csswg.org/css-animations-2/ Editor: L. David Baron, Mozilla, dbaron@dbaron.org !Issues List: In Bugzilla Abstract: This CSS module describes a way for authors to animate the values of CSS properties over time, using keyframes. The behavior of these keyframe animations can be controlled by specifying their duration, number of repeats, and repeating behavior. Ignored Vars: auto-rewind
urlPrefix: https://w3c.github.io/web-animations/; type: interface; spec: web-animations
text: Animation
text: KeyframeEffectReadOnly
urlPrefix: https://w3c.github.io/web-animations/; type: method; for: Animation; spec: web-animations
text: play()
text: pause()
urlPrefix: https://w3c.github.io/web-animations/; type: method; for: KeyframeEffectReadOnly; spec: web-animations
text: getFrames()
urlPrefix: https://w3c.github.io/web-animations/; type: dfn; spec: web-animations
text: animation
text: animation playback rate
text: animation class
text: composite operation
text: current iteration
text: current time
text: global animation list
text: idle play state
text: pause an animation
text: play an animation
text: sampling
text: start delay
text: target element
text: target effect
text: target effect end
This is a delta specification, meaning that it currently contains only the differences from CSS Animations Level 1 [[!CSS3-ANIMATIONS]]. Once the Level 1 specification is closer to complete, it will be merged with the additions here into a complete level 2 specification.
# Animations # {#animations} ## Owning element ## {#owning-element-section} The owning element of an animation refers to the element or pseudo-element to which the 'animation-name' property was applied that generated the animation. If an animation was generated directly by script (e.g. using the {{CSSAnimation}} constructor) then it has no owning element. If an animation generated using the markup defined in this specification is later disassociated from that markup by an update to the computed value of the 'animation-name' property on the owning element, the animation is disassociated from its owning element (that is, it has no owning element from that point forwards).animation's initial owning element
is elem. animation is disassociated from
element through an update to the computed value of
elem's 'animation-name' property.
elem.style.animation = 'spin 1s'; let animation = elem.getAnimations()[0]; // animation's owning element is elem elem.style.animation = ''; // animation no longer has an owning elementNote that although the owning element is often equal to the target element of an animation's target effect, this is not always the case. The following example demonstrates some of the situations where these two elements may differ.
elem.style.animation = 'move 1s'; let animation = elem.getAnimations()[0]; // animation.effect.target == elem == animation's owning element let mutableEffect = animation.effect.clone(); animation.effect = mutableEffect; animation.effect.target = elem2; // animation.effect.target == elem2 != animation's owning element animation.effect = null; // animation.effect.target is undefined != animation's owning element
| Initial state | ||||||
|---|---|---|---|---|---|---|
| Event | A | B | C | D | E | |
| Resulting state | {{Animation/play()}} | A | B | A | B | B |
| {{Animation/pause()}} | C | D | C | D | D | |
| 'animation-play-state' → ''running'' | A | A | C | C | A | |
| 'animation-play-state' → ''paused'' | E | B | D | D | E | |
Name: animation-composition Value: <<single-animation-composition> = replace | add | accumulate The values of 'animation-composition' have the meaning defined for the corresponding values of the composite operation defined in Web Animations [[!WEB-ANIMATIONS]]. 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.># Initial: replace Applies to: all elements, ::before and ::after pseudo-elements Inherited: none Animatable: no Percentages: N/A Media: interactive Computed value: As specified Canonical order: per grammar
@keyframes heartbeat {
from {
scale: 1;
animation-timing-function: ease-out;
}
30% {
scale: 1.3;
}
}
.heartbeat {
animation: heartbeat 0.3s 2s infinite;
}
@keyframes throb {
50% {
scale: 1.8;
}
}
.icon:mouseover {
animation: throb 0.4s add;
}
If these two animations are applied to the same element, normally only
one animation would apply, but by specifying ''add'' as the
'animation-composition' on the second animation, the result of the two
animations will be combined.
Since CSS Transitions [[CSS3-TRANSITIONS]] have a lower composite
order, it is possible to use 'animation-composition' to combine CSS
Animations with underlying transitions as in the following example.
.icon {
filter: blur(20px);
transition: filter 0.5s;
}
.icon:hover {
filter: blur(0px);
animation: brightness-pulse 3s infinite add;
}
@keyframes pulse {
0% {
scale: 1.1;
filter: brightness(130%);
}
10% {
scale: 1;
filter: brightness(100%);
}
}
Issue: Create pictures of these examples and verify they make sense.
AnimationEvent ## {#event-animationevent}
The additional types of animation events that can occur are:
elapsedTime for each case.
# DOM Interfaces # {#interface-dom}
## The CSSAnimation interface ## {#the-CSSAnimation-interface}
interface CSSAnimation : Animation {
readonly attribute DOMString animationName;
};
: animationName
:: The key used to find matching keyframes rules that define target
effect at the point when the animation was created.
This is the value of the 'animation-name' property that caused this
object to be generated or, if this object was generated using the
programming interface, the animationName argument
that was passed to the {{CSSAnimation}} constructor.
[Constructor (Animatable? target,
DOMString animationName,
optional (unrestricted double or KeyframeEffectOptions) options,
optional DOMString defaultEasing = "ease"),
Constructor (Animatable? target,
DOMString animationName,
(unrestricted double or KeyframeEffectOptions) options,
DOMString defaultEasing,
AnimationTimeline? timeline)]
partial interface CSSAnimation { };
The difficulty is with liveness. The most useful and least magical
(but most complicated) approach is to define a subclass of
{{KeyframeEffectReadOnly}} that has the special behavior of tracking changes
to all @keyframes rules that match the supplied name and automatically
updating the set of keyframes returned by
{{KeyframeEffectReadOnly/getFrames()}} after filling-in the default easing.
Something like,
[Constructor (DOMString keyframesName, DOMString defaultEasing)]
interface CSSKeyframeEffectReadOnly : KeyframeEffectReadOnly {
readonly attribute DOMString keyframesName;
readonly attribute DOMString defaultEasing;
};
elem is initially updated, a user agent may defer recalculating
the computed value of the 'animation' property.
However, the {{Animatable/getAnimations()}} method called on elem
is specified by Web Animations and can return {{CSSAnimation}} objects as
defined in this specification.
Hence, as result of the requirements in this section, the user agent must
calculate the updated value of elem's 'animation' property and
create the requested {{CSSAnimation}} object before returning its result.
elem.style.animation = 'fadeOut 1s'; elem.getAnimations()[0].pause();