CSS Easing Visualizer shows animation timing functions as interactive graphs and live preview animations. Choose from built-in keywords (ease, linear, ease-in, ease-out, ease-in-out) or create custom cubic-bezier() curves by dragging control points. Instantly see how the easing function affects motion, copy the CSS value, and preview it on a moving element to feel the timing before using it in production.
CSS animation timing is controlled by the animation-timing-function (or transition-timing-function) property. The value describes how an animation progresses through its duration -- not the speed itself, but the rate of change. Built-in keywords: linear (constant speed), ease (slow start, fast middle, slow end -- default), ease-in (slow start, accelerates), ease-out (fast start, decelerates), ease-in-out (slow at both ends). All keywords map to cubic-bezier() curves: ease = cubic-bezier(0.25, 0.1, 0.25, 1.0).
Modern CSS also supports: steps() for frame-by-frame animation (steps(4, end) for 4 discrete steps). The linear() function (CSS Animations Level 2) lets you define arbitrary easing curves with multiple points, enabling spring-physics-like effects purely in CSS. For realistic motion, follow physics-inspired easing: UI elements that appear use ease-out (decelerate into position). UI elements that disappear use ease-in (accelerate away). Elements that move from A to B without appearing/disappearing use ease-in-out.
Smooth entrance animation
Result: cubic-bezier(0, 0, 0.2, 1) -- decelerates strongly at end (Material Design 'standard easing')
Bounce-like overshoot
Result: cubic-bezier(0.34, 1.56, 0.64, 1) -- control points outside 0-1 range create overshoot effect
Spring physics feel
Result: linear(0, 0.009, 0.035 2.1%, 0.141, 0.281 6.7%, 0.723 12.9%, 0.938 16.7%, ...) -- CSS linear() for spring
What is cubic-bezier() and how do the four values work?
cubic-bezier(x1, y1, x2, y2) defines a bezier curve with two control points. The start point is always (0,0) and end point is always (1,1). x1, x2: control the time axis (must be 0-1 -- values outside this range are invalid and will be clamped). y1, y2: control the value/progress axis (can be outside 0-1 -- this creates overshoot or undershoot effects). Example: cubic-bezier(0.25, 0.46, 0.45, 0.94) is ease-out. cubic-bezier(0.55, 0.055, 0.675, 0.19) is ease-in. Tools like Lea Verou's cubic-bezier.com, Chrome DevTools (click the curve icon next to timing functions), and this visualizer let you drag points to find the perfect curve.
What easing functions should I use for UI animations?
Google Material Design guidelines provide a good mental model: Standard easing (elements moving within the screen): cubic-bezier(0.4, 0, 0.2, 1) -- fast middle, eased at both ends. Deceleration easing (elements entering the screen, like modal appearing): cubic-bezier(0, 0, 0.2, 1) -- starts fast, decelerates. Acceleration easing (elements leaving the screen, like modal closing): cubic-bezier(0.4, 0, 1, 1) -- accelerates. Linear: for infinite loops (spinner rotation), opacity fades where linear feels natural. Avoid ease-in for elements entering -- it feels slow to start and wrong for things appearing. Physics: things in motion stay in motion, so departing elements should accelerate.
What is the CSS steps() timing function used for?
steps(n, jumpterm) creates a stepped animation with discrete jumps instead of smooth interpolation. n: number of equal-width steps. jumpterm: jump-start (step at start of each interval), jump-end or end (step at end -- default), jump-both (step at both start and end), jump-none (no step at either end). Common uses: sprite sheet animation (steps(8) moves through 8 frames). Typewriter effect (steps(n) where n = number of characters). Mechanical/retro feel. Example: @keyframes type { from { width: 0; } to { width: 100%; } } animation: type 2s steps(30, end). The cursor blink effect uses: animation: blink 1s steps(2, start) infinite.
What is the CSS linear() timing function?
CSS linear() (2023, supported in Chrome 113+, Firefox 112+, Safari 17+) allows defining arbitrary easing curves using multiple progress values. Unlike cubic-bezier (limited to one curve segment), linear() can create complex spring physics, bounce effects, and irregular easings. Syntax: linear(value1, value2 percentage%, ...). Example spring: transition-timing-function: linear(0, 0.009, 0.035 2.1%, 0.141, 0.281 6.7%, 0.723 12.9%, 0.938 16.7%, 1.02 20.8%, 1.055 23.1%, 1.07, 1.073 27.2%, 1.057 32.4%, 1 38.1%, 0.984 44.6%, 0.996 51.7%, 1.001 57.4%, 1). The css-generators.com/spring-easing/ tool generates these values from spring physics parameters (mass, stiffness, damping).
How do I add easing to CSS transitions and animations?
For transitions: transition: all 0.3s ease-out; -- applies ease-out to all transitioned properties. transition: opacity 0.2s ease-in, transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1); -- different easings per property. For animations: @keyframes slide-in { from { transform: translateY(-20px); opacity: 0; } to { transform: translateY(0); opacity: 1; } } .element { animation: slide-in 0.4s ease-out forwards; }. You can also specify different timing per keyframe: @keyframes bounce { 0% { animation-timing-function: ease-out; } 50% { animation-timing-function: ease-in; } }. For JavaScript animation: element.animate([{...}, {...}], { duration: 300, easing: 'cubic-bezier(0.4, 0, 0.2, 1)' }).