F2F/Seattle 2011/Agenda/Animations/Harmonisation
Executive summary
The relationship between SMIL Animation in SVG and CSS Animations/Transitions needs to be clearly established in order to guide future development of these specifications. To that end, a brief comparison between the two technologies is provided. Subsequently some concrete suggestions are offered on how we might proceed. Merging the two technologies seems difficult but aligning them may be possible.
Definitions
From this point forward, the following definitions will be used:
SVG Animation = SMIL Animation as used in SVG (!= SMIL Animation != SMIL 3.0)
CSS Animation = CSS Transitions + CSS Animations
SVG Animation x CSS Animation
Animation target
- CSS: a set of properties on matched elements
- SVG: one attribute on one element
div { animation-name: 'diagonal-slide'; animation-duration: 5s; animation-iteration-count: 10; } @keyframes 'diagonal-slide' { from { left: 0; top: 0; } to { left: 100px; top: 100px; } } <animate xlink:href="#rect1" attributeName="left" from="0" to="100px" dur="5s" repeatCount="10"/> <animate xlink:href="#rect1" attributeName="top" from="0" to="100px" dur="5s" repeatCount="10"/>
Summary: Target selection fundamentally different. SVG lacks animation re-use (proposed - for example a selector attribute on the animation elements [1])
Animation values
Combining with underlying value:
- CSS: always overrides underlying style
- SVG: can add to or override in various ways (
additive="sum"
, by-animation, to-animation)
Combining with other animations:
- CSS: only one animation can target a property (proposal to introduce additive property to CSS animations)
- SVG: can add to or override other animations (
additive="sum/replace"
)—complex rules for determining priorities of competing animations (begin time, doc order, sync dependencies)
Combining with itself:
- CSS: When an animation repeats it goes back to the start
- SVG: Either returns to start, or builds on final value (
accumulate="sum"
)
Before/after animation is complete:
- CSS: determined by
animation-fill-mode
property which allows extension in both directions (i.e. before the animation started) - SVG: determined by
fill
attribute (fill="freeze"
means last value continues to apply, i.e. after only)
Summary: SVG offers a range of features for combining animations together and with the underlying value.
Animation types
- CSS: Linear/piecewise-constant interpolation
- SVG: Linear/piecewise-constant interpolation + animation along a path
Some differences:
- Integers: CSS: use
floor
, SVG: round - Colors: CSS: sRGB, SVG: sRGB / linearRGB (depends on
color-interpolation
) - Paint servers: CSS: gradients with same no. of stops can be interpolated, SVG: no (but you can animate the gradient itself and its
<stop>
s)
Summary: Interpolation types and methods have some variation.
Interval timing
Animation begin
- CSS: doc load/style resolution (incl. UI events:
:hover
, DOM manipulation:setAttribute("class",...)
) - SVG: doc load/events (not just UI)/accesskey/DOM (
beginElement
)/syncbase/wallclock ☺
Begin delay
- CSS:
transition/animation-delay
- SVG: All begin times allow an offset to be applied
Terminating an animation
- CSS: remove from
animation-name
- SVG:
end
attribute: same sorts of values as begin (a set time/event firing/syncbase etc.)
Restarting
- CSS: remove from
animation-name
and re-add - SVG: if
restart="always"
the animation can restart mid-animation if another begin condition is satisfied
Repeating
- CSS:
animation-iteration-count
: >= 0.0 | "infinite" - SVG:
repeatCount
: > 0.0 | "indefinite";repeatDur
Summary: Interval timing is fundamentally different. The CSS timing model is primarily event-based (animations start when the document loads or a style is resolved). The SMIL timing model combines an event-based model with a scheduling model (many intervals can be scheduled in advance).
SMIL has complex (and confusing) rules for establishing intervals, e.g.
- Zero-duration intervals ok, but not two in a row
- If there's an end condition and all end times are before the next begin time the animation will not play—acts like a hard clamp
- Once an interval (other than the first) is started, certain begin/end times are cleared
This is a significant difference.
Timing functions
Keyframing
- CSS:
@keyframes
- SVG:
keyTimes
@keyframes 'wobble' { 0% { left: 100px; } 40% { left: 150px; } 60% { left: 75px; } 100% { left: 100px; } } <animate attributeName="left" values="100px; 150px; 75px; 100px" keyTimes="0; 0.4; 0.6; 1" ... />
Timing functions
- CSS: cubic bezier curve, discrete steps
- SVG: cubic bezier curve (lacks CSS' keywords
ease-in
etc.), discrete steps (not as flexible as CSS), paced (even pace of change, especially for motion on a path)
@keyframes 'bounce' { from { top: 100px; animation-timing-function: ease-out; } 25% { top: 50px; animation-timing-function: ease-in; } 50% { top: 100px; animation-timing-function: ease-out; } 75% { top: 75px; animation-timing-function: ease-in; } to { top: 100px; } } <animate attributeName="top" values="100px; 50px; 100px; 75px; 100px" calcMode="spline" keyTimes="0; 0.25; 0.5; 0.75; 1" keySplines="0 0 0.58 1; 0.42 0 1 1; 0 0 0.58 1; 0.42 0 1 1"/>
Reversing
- CSS Transitions: Automatic reversing of animation (does ease-in remain ease-in? Discussion threads: [2] and [3])
- CSS Animations:
animation-direction
- allows alternating direction on repeat; ease-in becomes ease-out. Otherwise separate animation required. - SVG: --
Summary: Timing functions are mostly comparable (with minor differences, CSS lacks 'paced', SVG lacks keywords and some step functions). However, SVG does not allow mixing types of animation functions (e.g. discrete/cubic bezier/paced) within the one animation definition. Also, SVG lacks any reversing functionality.
DOM functions
DOM interfaces
- CSS:
- Per-animation: pause/unpause, query pause/play state (
animation-play-state
—may be dropped?)
- Per-animation: pause/unpause, query pause/play state (
- SVG:
- Per-animation: start/stop animation (
beginElement(At)/endElement(At)
), query start time, current time, duration (interfaceSVGAnimationElement
) - Per-document: pause/unpause, get/set current time (i.e. seeking, interface
SVGSVGElement
)
- Per-animation: start/stop animation (
Events
- CSS Transitions: TransitionEvent (type: transitionend). Context info: propertyName, elapsedTime
- CSS Animations: AnimationEvent (type: animationstart/animationend/animationiteration). Context info: animationName[, elapsedTime]
- SVG: TimeEvent (type: beginEvent/endEvent/repeatEvent). Context info: repeat iteration.
Manipulating timing
- CSS: Interfaces for manipulating keyframe rules
- SVG: Standard DOM interfaces (plus above-mentioned animation-specific methods)
Summary: DOM interfaces are fairly different. SVG lacks per-animation pause control but otherwise offers more control. The difference in event names is unfortunate.
DOM modifications
- CSS: The values used for the keyframes and animation properties are snapshotted at the time the animation starts.
- SVG: Not specified. (Dynamic changes allowed?)
Other fundamental differences
Approach to script
- CSS: assumes script is possible—e.g. restarting requires script
- SVG: tries to remain declarative. A significant use case for SVG animation is SVG assets (SVG backgrounds, fonts, cursors, favicons, <img> etc.) where script is not available
Harmonisation
Danger of creating a confusing platform of overlapping techologies that are subtlely different and incompatible.
Possible approaches
- Drop SVG Animation altogether and extend CSS Animations
- Merge the two into one master Web Animations spec with two syntaxes: CSS and XML
- Leave them as two separate technologies but make them play well together
- Assign clear roles to each so web developers can easily judge when to use which
- Make overlapping areas overlap properly (e.g. align syntax, interpolation rules)
- Where either technology is suitable make them interchangeable
(The following analysis was helped hugely by Cameron's notes: http://www.w3.org/Graphics/SVG/WG/wiki/Talk:F2F/Auckland_2011/CSS_Animation)
Option 1: Drop SVG Animation altogether and extend CSS Animations
Following are some of the features that SVG currently offers that CSS does not. We needn't necessarily import all of them into CSS but this gives some idea of the scale of the task if we want to provide roughly equivalent functionality.
- Combining with the underlying value: e.g. applying supplemental transformations to an element that already has a transform applied.
- Also includes special types of animation like to-animation and by-animation
- Combining independent animations of the same property: e.g. a 'swell' animation and 'spin' animation applying at once.
- Animation along a path
- Including "paced" animation which is most useful in this context
- Begin/End in response to arbitrary events, other animations, etc.
- End/Restart without script
- Scheduled timing (e.g. begin="2s; 5s")
- Adding this to CSS means determining if and when animations can automatically restart (SVG has
restart="never|whenNotActive|always"
)
- Adding this to CSS means determining if and when animations can automatically restart (SVG has
- Synchronisation between animations
- Means defining what sort of cyclic references are permitted and how they should be broken
- Cumulative repeats
- Fill behaviour (i.e. continuing to affect animated value after animation has finished)
- Document-level pause control
- Document-level seeking
Option 2: Merge the two into one master Web Animations spec with two syntaxes
Based on the above analysis, I think there are fundamental differences that make merging difficult. It would likely involve dropping compatibility with one technology or the other. (If we drop compatibility with SVG then it's basically Option 1.)
UPDATE: On further consideration, I'm not sure it's impossible. It will probably involve some backwards-incompatibility but it's possible that such incompatibility is only minor.
Option 3: Make SVG Animation and CSS Animation play well together
Assign clear roles to each so web developers know when to use each
- For example, CSS Animation as a simplified SVG Animation. Ensure the functionality of CSS Animation is a subset of SVG Animation
- → if you find yourself hitting the wall with CSS, time to consider SVG
- Means adding to SVG anything missing that's in CSS: e.g. reversing, re-usable animations
- Are there other ways of separating their roles?
Make overlapping areas overlap properly
Align syntax
- Add CSS'
transition/animation-timing-function
keywords to SVG- Also involves allowing mixing timing functions within the one animation (currently only one
calcMode
per animation)
- Also involves allowing mixing timing functions within the one animation (currently only one
- Rename / alias events? Standardise on which one? TimeEvent vs AnimationEvent? beginEvent vs animationstart?
Make interpolation consistent
- Integer rounding
- Color space interpolation—ok to leave CSS as just sRGB? Add HSL to SVG?
- CSS Transitions needs to specify if interpolation is in premultiplied space or non-premultiplied and SVG should do likewise if it ever does RGBA colors.
- In future, SVG's
<animate>
should be able to target a transform list (obsoleting<animateTransform>
on the way) and should try to align with the animation definitions in CSS Transforms for this. - Cameron also notes that we it would be good to have definitions for how all CSS properties animate even if they're not interpolatable, e.g. fallback to discrete animation. [4]
Where either technology is suitable make them interchangeable
CSS animating SVG — Allow CSS to animate SVG attributes too?
- Cameron has pointed out some of the problems with
- Promoting SVG attributes to properties
- Introducing new properties
- See: http://www.w3.org/Graphics/SVG/WG/wiki/Talk:F2F/Auckland_2011/CSS_Animation#Using_CSS_Transitions.2FAnimations_with_current_SVG_attributes
- So in Auckland we proposed going with the
attr()
syntax to allow CSS Animations to target SVG attributes.- There was some outstanding concern about whether this syntax could appear on the LHS (particularly re CSS Transitions)
- See: http://lists.w3.org/Archives/Public/public-svg-wg/2011JanMar/0199.html
- Would the animation result be stored in the animVal? i.e. acts as an additional animation of lowest priority (applies before SVG Animations)
- See also Cameron's notes about this: http://www.w3.org/Graphics/SVG/WG/wiki/Talk:F2F/Auckland_2011/CSS_Animation#Using_CSS_Transitions.2FAnimations_with_current_SVG_attributes
SVG animating CSS
- Allow SVG animation to target non-SVG content?
- May be necessary if we decide that CSS Animation is a subset of SVG Animation
- Might mean adding further definitions for what addition means for various CSS types?
Allow SVG animations to be used as an animation-name
- This will require reworking SVG Animations to make them re-usable which is already proposed.
- Does an animation applied in this way still alter SVG animVals in the DOM? But is lowest priority?
- Cameron has put forward some concrete suggestions about the effect of applying CSS Animation properties to SVG Animations: http://www.w3.org/Graphics/SVG/WG/wiki/Talk:F2F/Auckland_2011/CSS_Animation#Applying_the_CSS_Animation_properties_to_SVG_Animations
Synchronisation between the two?
- Allow CSS Animation names to appear in SVG syncbase timing specifications?
- The other direction (triggering CSS Animations from SVG) should already be possible in a limited fashion: Use a
<set>
animation to change aclass
attribute. However, this won't give proper behaviour in the case of a seek.