Normative notes for the behavior in Animation/ where the specifications leave room or the engine differs. The tests and the WPT replay are named in architecture.md.
Choices
- Before-change style. The style a transition starts from is the previous tree's style of the same element as the page last showed it, so a running transition or animation counts at its current value (Transitions 1 §3 says the same for transitions, and for animations in the "before-change style" definition).
- Reversal. A transition whose end value equals the start of a running one reverses with the shortening factor and reversing-adjusted start of Transitions 1 §3.2.
- Discrete transitions.
allow-discretetransitions flip at the midpoint, exceptdisplay: a transition withnoneat one end keeps the other value for the whole interval, and a transition ofdisplayfromblocktononekeeps the element displayed until it ends. An element whose after-changedisplayisnonestarts no other transition and runs no animation (Transitions 2 §3.1). - Keyframes.
unsetin a keyframe meansinheritorinitialby property. Declarations marked!importantand custom properties in a keyframe are ignored. The implicit 0% and 100% keyframes take the element's underlying value. Animation names compare case-sensitively;"none"as a string is an animation named none. - Computed text.
animation-namekeeps names that read as keywords quoted; identifiers are escaped (CSSOM "serialize an identifier").steps(n, start)andsteps(n, jump-start)serialize as written.animation-duration: autocomputes to0s(no scroll timelines).transition-propertykeeps the case of unknown names. Times and the iteration count acceptcalc()and the other math functions that need no layout context. - Ends of a length mix. Interpolating a px length with a percentage gives
calc(); at the end of the range the result is the end value itself, at the start it stays a sum such ascalc(0% + 40px)(matches Chrome 156, and the WPT interpolation tests expect it). vertical-align.baselinetakes part in interpolation as the zero offset.- Colors. All colors interpolate premultiplied in sRGB, whatever syntax they were written in. A color written in
oklab()or another space interpolates in sRGB too, so a mid-point differs slightly from Chrome.currentcolorin a shadow or filter resolves against the element's cascadedcolor. - Serialization of channels. Color channels round half away from zero when serialized (
rgb(178.5)is 179). - Events.
animationiterationis dispatched for the iteration boundary a frame lands in; an iteration boundary skipped by a late frame is not repeated.transitionendandanimationendcarry the elapsed time of the whole effect. A cancelled effect that never started a run (a transition cancelled before its first tick) fires nothing. - Order of effects. Base style, then transitions, then animations in the order of
animation-name; a later animation of the same property wins.
Known deviations
- Colors in
oklab()/oklch()/color-mix()do not interpolate in their own space. font-sizeanimation does not recomputeemlengths of element descendants (text follows).- Animated colors, shadows and filters repaint and are not patched in place; only transform and opacity are.
- Pseudo-elements,
::markerand::first-linedo not animate. animation-composition,animation-timeline,animation-rangeandvar()inside@keyframesare not implemented.- A change that adds or removes elements from the styled tree (a
display: noneflip, generated content, list markers) builds the page again; transitions the same change started were already registered by then, and the second pass finds them running. - A page parsed without
HtmlPageOptions.AnimationTimeand not wrapped inInteractivePageis static.
Replay of the WPT helpers
testdata/wpt-motion/ holds the css-transitions and css-animations testharness files that need no script: the parsing/ files (replayed like the other parsing files, WptStyleRunner) and the files calling test_interpolation, test_no_interpolation and test_not_animatable. For the latter, WptMotionRunner rebuilds what the helper builds: a target and a reference element, the reference carrying the expected value as a plain declaration; the target gets a 100 s animation or transition with a -50 s delay and the helper's timing function, which yields the wanted progress at the midpoint. A transition starts from a style change (focusing the target). The comparison is the engine's own computed text on both sides. The Web Animations variant of the helper, composition tests and everything that needs promises, getAnimations(), event handlers or frames are excluded with a reason in excluded.tsv. expected-failures.tsv lists every replayed failure with its reason; floors.tsv holds each module's rate, which only rises.