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.

Syntaxcubic-bezier( [ <number [0,1]>, <number> ]#{2} )
Returns<easing-function>
SupportChrome 16 · Firefox 4 · Safari 6
Speccss-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.

KeywordSame asFeels like
easecubic-bezier(0.25, 0.1, 0.25, 1)Quick start, gentle finish. The default for transitions and animations.
linearcubic-bezier(0, 0, 1, 1)Constant speed throughout.
ease-incubic-bezier(0.42, 0, 1, 1)Starts slowly and speeds up; suits things leaving.
ease-outcubic-bezier(0, 0, 0.58, 1)Starts fast and slows down; suits things arriving.
ease-in-outcubic-bezier(0.42, 0, 0.58, 1)Slow at both ends.
step-startsteps(1, jump-start)Jumps to the end value immediately.
step-endsteps(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);
A y value above 1 makes the element overshoot slightly, then settle.

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.

Syntaxsteps( <integer>, <step-position>?)
Returns<easing-function>
Supportsteps(): Chrome 8 · Firefox 4 · Safari 5.1
jump-* step positions: Chrome 77 · Firefox 65 · Safari 14
Speccss-easing-2
Step positionEffect
jump-end or endThe default. The first jump happens after the first interval, so the end value is reached only as the animation finishes.
jump-start or startThe first jump happens at the very start.
jump-noneNo jump at either end: the start and end values each hold for one interval. Needs at least 2 steps.
jump-bothJumps at both the start and the end, giving one more visible value than the number of steps.
animation: walk 0.8s steps(8) infinite;
Play an eight-frame sprite sheet without blending between frames.

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.

Syntaxlinear( [ <number> && <percentage>{0,2} ]# )
Returns<easing-function>
SupportChrome 113 · Firefox 112 · Safari 17.2
Speccss-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);
A simple bounce: the value reaches 1, drops back twice and settles.

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.

Syntaxscroll( [ <scroller> || <axis> ]? )
ReturnsA scroll progress timeline, as a value of animation-timeline
SupportChrome 115 · Firefox 159 · Safari 26
Specscroll-animations-1
@keyframes grow { from { scale: 0 1; } }
.progress { transform-origin: left; animation: grow linear; animation-timeline: scroll(root); }
A reading progress bar that fills as the page scrolls.

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.

Syntaxview( [ <axis> || <'view-timeline-inset'> ]? )
ReturnsA view progress timeline, as a value of animation-timeline
SupportChrome 115 · Firefox 159 · Safari 26
Specscroll-animations-1
@keyframes reveal { from { opacity: 0; translate: 0 2rem; } }
.card { animation: reveal linear both; animation-timeline: view(); animation-range: entry; }
Cards that fade and slide in as they scroll into view.