Animations
An animate block attaches an animation to a property.
Whenever that property’s value changes, the value moves to its target over time rather than jumping to it at once:
export component Example inherits Window { background: area.pressed ? blue : red; animate background { duration: 250ms; } area := TouchArea {}}An animate block is a statement inside an element’s body.
It may appear on any element — the root, a child, or a sub-component’s root.
A global may not contain an animate block; doing so is a compile error.
The animate keyword is followed by one or more property names and a brace-delimited body of bindings:
animate <property> { // field: value;}- Each name refers to a property of the element the
animateblock sits on. A qualified name such asother.propertyis not allowed here; it is a compile error to refer to a property of another element. - The body may contain only bindings of the form
field: value;. Any other statement is a compile error. - The only fields are
delay,duration,easing,iteration-count,direction, andenabled. Binding any other name is a compile error. Every field is optional.
Attaching two animate blocks to the same property is a compile error.
Animatable properties
Section titled “Animatable properties”A property can be animated only when its type is one of:
int, float, length, physical-length, color, brush, or angle.
Animating a property of any other type — for example a string, bool, image, or struct property — is a compile error.
The property must also be settable on the element. Animating a property that cannot be assigned, such as a private property of another component, is a compile error.
Animating several properties
Section titled “Animating several properties”Listing several comma-separated names applies the same animation to each:
animate x, y { duration: 100ms; easing: ease-out-bounce; }is equivalent to:
animate x { duration: 100ms; easing: ease-out-bounce; }animate y { duration: 100ms; easing: ease-out-bounce; }Each named property must be animatable and settable, subject to the rules above.
Fields
Section titled “Fields”durationdefault: 0ms
The amount of time to wait before the animation starts.
duration
Section titled “duration”durationdefault: 0ms
The amount of time the animation takes to complete.
iteration-count
Section titled “iteration-count”floatdefault: 1
The number of times the animation runs. A negative value runs it forever. Fractional values are allowed. For a continuously running value independent of property changes, see `animation-tick()`.
easing
Section titled “easing”easingdefault: linear
The easing curve applied over the animation’s duration.
See easings.net ↗ for a visual reference.
direction
Section titled “direction”enum AnimationDirectiondefault: the first enum value
The direction in which each iteration plays.
AnimationDirection
This enum describes the direction of an animation.
normal: The “normal” direction as defined in CSS ↗.reverse: The “reverse” direction as defined in CSS ↗.alternate: The “alternate” direction as defined in CSS ↗.alternate-reverse: The “alternate reverse” direction as defined in CSS ↗.
enabled
Section titled “enabled”booldefault: true
Whether the animation runs.
When false, a change sets the property to its target value at once, with no delay, easing, or iteration.
Transitions
Section titled “Transitions”Inside a transition an animate block instead describes how the property moves when the state changes.
There a name may be qualified, as in animate root.background { ... }, so a transition can animate properties of nested elements.
The fields are the same as above.
See States and Transitions for where transitions are written and how they select which animation applies.
Spring Animations
Section titled “Spring Animations”The spring easing curve takes an optional bounce argument, for example spring(0.4).
The bounce must be a number literal between -1 and 1; any other argument is a compile error.
Writing just spring is the same as spring(0).
Since duration helps define the spring’s natural frequency ↗, the animation is not guaranteed to be done after duration elapses.
If bounce is close to 0, the animation will be nearly done, however the further from 0 bounce is, the longer the animation will take.
A spring with a finite iteration-count cannot oscillate forever. It is clamped to at most (iteration-count + 9) x duration in total.
When iteration-count is set to -1, this clamp never applies.
Every iteration up to iteration-count runs at bounce.
If the spring hasn’t settled by the end of the final iteration’s duration, it’s re-damped so it settles within a further 9x duration (10x duration in total from the start of the last iteration).
An iteration-count of -1 makes the animation infinite, and a bounce of 1 makes the loop seamless.
See Iterations and Directions below for why.
Unlike other easing curves, springs maintain velocity on retarget, so it keeps moving smoothly instead of jumping to a new curve.
Bounce values
Section titled “Bounce values”bounce= 0: the value approaches the target as quickly as possible without overshooting it (critically damped).bounce> 0: the value approaches the target quickly but overshoots it (underdamped) — the closer to 1, the longer it takes to settle.bounce< 0: the value approaches the target slowly without overshooting it (overdamped).
Spring Example
Section titled “Spring Example”export component Example inherits Window { width: 200px; height: 100px;
ball := Rectangle { x: area.pressed ? 150px : 0px; width: 50px; height: 50px; border-radius: 25px; background: blue; animate x { duration: 500ms; easing: spring(0.5); } } area := TouchArea {}}Details
Section titled “Details”The spring’s animation relies on the natural frequency ↗(ω₀ = 2π/duration) and the damping ratio ↗(ζ = 1 - bounce) to feed the mass-spring-damper model ↗.
Iterations and Directions
Section titled “Iterations and Directions”Because a spring is not guaranteed to settle by duration, a repeating spring animation
(iteration-count greater than 1) moves on to its next iteration at exactly duration, rather than
waiting for the spring to fully settle.
The spring’s velocity always carries over into the next iteration. What happens to its position depends on whether that iteration also flips direction:
- A same-direction repeat resets the position to the start of the animation, the same way a repeating easing-curve animation restarts from the top.
- A direction flip (
alternateoralternate-reverse) instead continues from wherever the spring actually is, so the value keeps moving smoothly instead of snapping to the far end.
Infinite continuous springs
Section titled “Infinite continuous springs”If bounce is set to 1, the period of the spring is exactly duration. If an object is animated from x = 0px to x = 100px,
this results in x == 0px at exactly duration. Since the next iteration starts at exactly duration, as long as direction
is not alternate or alternate-reverse, an iteration-count of -1 will be an infinite continuous spring. If bounce is set to values
other than 1, the position will not quite be at either end of the animation and there will be a noticeable jump.
© 2026 SixtyFPS GmbH