Title: CSS Animations Level 2 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 https://www.mozilla.org/, https://dbaron.org/, w3cid 15393 Editor: Brian Birtles, Mozilla https://www.mozilla.org/, bbirtles@mozilla.com, w3cid 43194 !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://dom.spec.whatwg.org/; type: dfn; spec: dom text: event target
spec:web-animations-1; type:dfn; text:active duration text:active phase; for:animation effect text:active time text:after phase; for:animation effect text:animation class text:animation effect text:animation playback events text:associated effect text:associated effect end text:before phase; for:animation effect text:current iteration text:current time; for:animation text:composite operation text:fill mode text:idle play state text:idle phase; for:animation effect text:iteration duration text:iteration count text:iteration start text:keyframe text:pause an animation text:paused play state text:pending pause task text:pending play task text:play an animation text:play state text:playback direction text:start delay text:target element text:unresolved
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} Changes to any of the animation properties defined in this specification cause the corresponding {{CSSAnimation}} object and its associated objects to be updated according to the correspondence between these properties and Web Animations concepts defined in [[#keyframes]]. However, if the author modifies the animation using the Web Animations programming interface, the changes from the programming interface take precedence as follows: * After a successful call to {{KeyframeEffect/setKeyframes()}} on the {{KeyframeEffect}} associated with a {{CSSAnimation}}, any subsequent change to matching ''@keyframes'' rules or the resolved value of the 'animation-timing-function' property for the target element will not be reflected in that animation. However, if the last matching ''@keyframes'' rule is removed the animation must still be canceled. * After a successful call to {{AnimationEffect/updateTiming()}} on the {{KeyframeEffect}} associated with a {{CSSAnimation}}, for each property included in the {{AnimationEffect/updateTiming(timing)/timing}} parameter, any subsequent change to a corresponding animation property will not be reflected in that animation. For example, callingcssAnimation.effect.updateTiming({ duration: 1000 })
would cause subsequent changes to 'animation-duration' to be ignored
whilst changes to 'animation-delay' would still be reflected
in the {{KeyframeEffect}}'s timing.
* After a successful call to {{Animation/play()}} or {{Animation/pause()}}
on a {{CSSAnimation}},
any subsequent change to the 'animation-play-state' will no longer
cause the {{CSSAnimation}} to be played or paused
as defined in [[#animation-play-state]].
* After a successful call to {{Animation/reverse()}} on a {{CSSAnimation}}
or after successfully setting the {{Animation/startTime}}
on a {{CSSAnimation}},
if, as a result of that call the [=play state=] of the
{{CSSAnimation}} changes to or from the [=paused play state=],
any subsequent change to the 'animation-play-state' will no longer
cause the {{CSSAnimation}} to be played or paused
as defined in [[#animation-play-state]].
The requirement for a change to or from the [=paused play state=]
ensures that even after calling
{{Animation/reverse()}} or setting the {{Animation/startTime}}
on a running animation,
the animation continues to observe changes in 'animation-play-state'.
* After successfully setting the {{Animation/effect}} of a {{CSSAnimation}}
to null
or some {{AnimationEffect}} other than the original {{KeyframeEffect}},
all subsequent changes to animation properties other than
'animation-name' or 'animation-play-state'
will not be reflected in that animation.
Similarly, any change to matching ''@keyframes'' rules will not be reflected
in that animation.
However, if the last matching ''@keyframes'' rule is removed
the animation must still be canceled.
Note, the reference to a successful call in the above rules
is necessary to ensure that
when an exception is thrown by any of these methods,
the override behavior is not applied.
## 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 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 [=associated 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 animation.effect.target = elem2; // animation.effect.target == elem2 != animation's owning element animation.effect = null; // animation.effect?.target is undefined != animation's owning element
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 Inherited: no Percentages: N/A Computed value: list, each item a keyword as specified Animation type: not animatable 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 brightness-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.
Name: animation-timeline Value: <># Initial: auto Applies to: all elements Inherited: no Percentages: N/A Computed value: list, each item either a case-sensitive [=css identifier=] or the keywords ''single-animation-timeline/none'', ''single-animation-timeline/auto''. Canonical order: per grammar Animatable: no
<single-animation-timeline> = auto | none | <The 'animation-timeline' property is similar to properties like 'animation-name' and 'animation-duration' in that it can have one or more values, each one imparting additional behavior to a corresponding [=animation=] on the element, with the timelines matched up with animations as described [[css-animations-1#animation-name|here]]. Each value has type <> | < > | < >
max(min(-start delay, active duration), 0)
* interval end =
max(min([=associated effect end=] - start delay,
active duration), 0)
Each time a new [=animation frame=] is established and the animation does
not have a [=pending play task=] or [=pending pause task=],
the events to dispatch are determined by
comparing the animation's phase before and after establishing the new
[=animation frame=] as follows:
Change | Events dispatched | Elapsed time (ms) |
---|---|---|
[=animation effect/idle phase|idle=] or [=animation effect/before phase|before=] → [=animation effect/active phase|active=] | {{animationstart}} | interval start |
[=animation effect/idle phase|idle=] or [=animation effect/before phase|before=] → [=animation effect/after phase|after=] ٭ | {{animationstart}} | interval start |
{{animationend}} | interval end | |
[=animation effect/active phase|active=] → [=animation effect/before phase|before=] | {{animationend}} | interval start |
[=animation effect/active phase|active=] → [=animation effect/active phase|active=] and the current iteration of the animation's [=associated effect=] has changed since the previous animation frame | {{animationiteration}} | (See below) † |
[=animation effect/active phase|active=] → [=animation effect/after phase|after=] | {{animationend}} | interval end |
[=animation effect/after phase|after=] → [=animation effect/active phase|active=] | {{animationstart}} | interval end |
[=animation effect/after phase|after=] → [=animation effect/before phase|before=] ٭ | {{animationstart}} | interval end |
{{animationend}} | interval start | |
not [=animation effect/idle phase|idle=] and not [=animation effect/after phase|after=] → [=animation effect/idle phase|idle=] | {{animationcancel}} | The active time of the animation at the moment it was cancelled calculated using a fill mode of both. |
٭ Where multiple events are listed for a state change, all events are dispatched in the order listed and in immediate succession.
† The elapsed time for an {{animationiteration}} event is defined as follows:
1. Let previous current iteration be the current iteration from the previous animation frame. 1. If previous current iteration is greater than current iteration, let iteration boundary becurrent
iteration + 1
, otherwise let it be current iteration.
1. The elapsed time is the result of evaluating
(iteration boundary - iteration start) ×
iteration duration)
.
Since the elapsed time defined in the table and procedure above is
expressed in milliseconds, it must be divided by 1,000 to produce a value in
seconds before being assigned to the {{AnimationEvent/elapsedTime}} member of
the {{AnimationEvent}}.
# DOM Interfaces # {#interface-dom}
## The CSSAnimation interface ## {#the-CSSAnimation-interface}
[Exposed=Window] interface CSSAnimation : Animation { readonly attribute CSSOMString animationName; };: animationName :: The key used to find matching keyframes rules that define the [=associated 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. ## Requirements on pending style changes ## {#requirements-on-pending-style-changes} Various operations may affect the computed values of properties on elements. User agents may, as an optimization, defer recomputing these values until it becomes necessary. However, all operations included in programming interface defined in this specification, as well as those operations defined in Web Animations [[!WEB-ANIMATIONS]] that may return objects or animation state defined by this specification, must produce a result consistent with having fully processed any such pending changes to computed values.
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();
elem.style.animation = 'fadeOut 1s paused'; const anim = elem.getAnimations()[0]; elem.style.animationPlayState = 'running'; console.log(anim.playState); // Should be 'running'.