Easing & timelines
The <easing-function> values that shape how a transition or animation moves between its start and end, used by transition-timing-function, animation-timing-function and the transition and animation shorthands, followed by the scroll() and view() functions that drive an animation by scrolling instead of time. The properties are under Transitions & animation and Scroll-driven animation.
Easing functions
cubic-bezier()
A smooth easing curve defined by two control points, cubic-bezier(x1, y1, x2, y2). The x values are progress through time and must be between 0 and 1; the y values are progress through the change and may go outside that range, which makes the motion overshoot and settle back.
| Syntax | cubic-bezier( [ <number [0,1]>, <number> ]#{2} ) |
|---|---|
| Returns | <easing-function> |
| Support | Chrome 16 · Firefox 4 · Safari 6 |
| Spec | css-easing-2 |
The easing keywords are shorthands for common curves and steps. All of them work in Chrome 4, Firefox 4 and Safari 3.1 or later.
| Keyword | Same as | Feels like |
|---|---|---|
ease | cubic-bezier(0.25, 0.1, 0.25, 1) | Quick start, gentle finish. The default for transitions and animations. |
linear | cubic-bezier(0, 0, 1, 1) | Constant speed throughout. |
ease-in | cubic-bezier(0.42, 0, 1, 1) | Starts slowly and speeds up; suits things leaving. |
ease-out | cubic-bezier(0, 0, 0.58, 1) | Starts fast and slows down; suits things arriving. |
ease-in-out | cubic-bezier(0.42, 0, 0.58, 1) | Slow at both ends. |
step-start | steps(1, jump-start) | Jumps to the end value immediately. |
step-end | steps(1, jump-end) | Holds the start value, then jumps at the end. |
transition: transform 0.4s cubic-bezier(0.34, 1.56, 0.64, 1);
steps()
Divides the change into a number of equal jumps instead of a smooth movement, for frame-by-frame sprite animation or ticking clocks. The optional step position says where the jumps happen.
| Syntax | steps( <integer>, <step-position>?) |
|---|---|
| Returns | <easing-function> |
| Support | steps(): Chrome 8 · Firefox 4 · Safari 5.1jump-* step positions: Chrome 77 · Firefox 65 · Safari 14 |
| Spec | css-easing-2 |
| Step position | Effect |
|---|---|
jump-end or end | The default. The first jump happens after the first interval, so the end value is reached only as the animation finishes. |
jump-start or start | The first jump happens at the very start. |
jump-none | No jump at either end: the start and end values each hold for one interval. Needs at least 2 steps. |
jump-both | Jumps at both the start and the end, giving one more visible value than the number of steps. |
animation: walk 0.8s steps(8) infinite;
linear()
An easing made of straight lines between a list of points, each an output value with an optional input position as a percentage. With enough points it can approximate bounces, springs and other curves that cubic-bezier() cannot.
| Syntax | linear( [ <number> && <percentage>{0,2} ]# ) |
|---|---|
| Returns | <easing-function> |
| Support | Chrome 113 · Firefox 112 · Safari 17.2 |
| Spec | css-easing-2 |
Points without a position are spread evenly between their neighbours. Two percentages on one point hold that value between the two positions.
animation-timing-function: linear(0, 0.25 25%, 1 50%, 0.8 62%, 1 75%, 0.95 87%, 1);
Animation timelines
scroll()
An anonymous scroll progress timeline for animation-timeline: the animation's progress follows how far a scroll container has been scrolled, from 0% at the top to 100% at the end. The scroller is nearest (the default, the nearest ancestor scroll container), root (the document) or self; the axis is block (the default), inline, x or y.
| Syntax | scroll( [ <scroller> || <axis> ]? ) |
|---|---|
| Returns | A scroll progress timeline, as a value of animation-timeline |
| Support | Chrome 115 · Firefox 159 · Safari 26 |
| Spec | scroll-animations-1 |
@keyframes grow { from { scale: 0 1; } }
.progress { transform-origin: left; animation: grow linear; animation-timeline: scroll(root); }
Set animation-timeline after the animation shorthand, because the shorthand resets it.
view()
An anonymous view progress timeline for animation-timeline: the animation's progress follows the element itself as it moves through the visible area of its nearest scroll container, from just entering to just leaving. The optional inset narrows or widens that area, as with view-timeline-inset.
| Syntax | view( [ <axis> || <'view-timeline-inset'> ]? ) |
|---|---|
| Returns | A view progress timeline, as a value of animation-timeline |
| Support | Chrome 115 · Firefox 159 · Safari 26 |
| Spec | scroll-animations-1 |
@keyframes reveal { from { opacity: 0; translate: 0 2rem; } }
.card { animation: reveal linear both; animation-timeline: view(); animation-range: entry; }