Front end

Better animation with the CSS linear() function

The CSS linear() function provides animation opportunities that were not possible before now.

4 minute read Front end Craig Buckler

CSS offers basic timing functions for animations and transitions. These include linear, ease-out, ease-in, and ease-in-out. They all define an animation curve which plots the progress of a property P over a time T starting at 0 and ending at 1 (your animation can occur over any period of time multiplied by this factor).

The progress P of an animated property -- such as opacity -- is defined by an easing function. The function returns a number when time T passed to it. The return value must be 0 when the animation starts (T is 0) and 1 when the animation ends (T is 1). It can return any other value at any other time (even one outside the range of 0 to 1).

The simplest to understand is linear: the progress P is identical to time T. Expressed as a JavaScript function, the value of P matches T:

function linear(T) { return T; }

At the half-way point, time T and progress P are both 0.5. Applying it to the CSS opacity property means it's halfway between fully transparent and fully opaque.

The following example uses:

animation-timing-function: linear;

applied to a ball element that starts at transform: translateY(0px) and ends at transform: translateY(300px):

<iframe src="./demo-linear.html" width="600" height="640"></iframe>

The ball animation looks unnatural because real world objects accelerate and decelerate as gravity and other forces apply as they move.

Easing keywords

CSS provides easing keywords named ease, ease-in, ease-out, and ease-in-out with more natural movement. ease-in-out accelerates for the half of the duration then decelerates for the last half:

<iframe src="./demo-ease.html" width="600" height="640"></iframe>

These functions may be adequate for simpler user interface animations, but this demonstration still does not look like a falling ball.

Bezier curve functions

You can define your own Bezier animation curves with two control points. These are more powerful since progress curves can go outside the 0 to 1 limit or come back on themselves and bounce. The following example uses:

animation-timing-function: cubic-bezier(0.7, 1.9, 0.6, 0.4);

where the first control point is at coordinate (0.7, 1.9) and the second is at (0.6, 0.4).

<iframe src="./demo-bezier.html" width="600" height="640"></iframe>

When defining control points:

  • The x-axis value of the coordinates must be between 0 and 1. This ensures the curve cannot curl back on itself.
  • The y-axis value of either coordinate can be any number. Using a value less than 0 or more than 1 can create a spring or bounce effect.

Browser DevTools and the Ceaser CSS Easing Animation Tool can help you create cubic-bezier() curves.

This can be adequate for simpler user interface animations, but the falling ball does not look natural:

  • the ball decelerates slightly before the bounce -- that's not how gravity works!
  • it only bounces once making it look unrealistically heavy.

The CSS linear() function

More sophisticated animations required JavaScript, some complex mathematical wrangling, and possibly a physics library. Until now.

Not to be confused with the linear easing keyword, the linear() function defines an animation "curve" as a series of stop-point lines. You can define any number of stop points to approximate a curve, but 12 points can create a natural-looking three-bounce animation:

animation-timing-function: linear(
  0, 0.06, 0.25, 0.56, 1, 0.81, 0.75, 0.81, 1, 0.94, 1 91%, 0.98, 1
);

<iframe src="./demo-linear-func.html" width="600" height="640"></iframe>

Pass stop points to the linear() function as a comma-separated list. Each point defines:

  1. The animation progress point P (required).
  2. One or two time duration points T between 0% and 100% (optional).

The following example is identical to the linear keyword:

animation-timing-function: linear(0 0%, 1 100%);

When you omit the time, the browser interpolates the timings so this is identical:

animation-timing-function: linear(0, 1);

The following example is more sophisticated:

animation-timing-function: linear(0, 0.1 25%, 0.1 50%, 1);
  1. The first tenth of animation progress P occurs in the first quarter of the duration.
  2. P remains at a tenth progress until half the duration has expired.
  3. The final 90% of animation progress P occurs over the last half of the duration.

linear() function points are tricky to code manually but there are tools that can help:

  • Most browser DevTools allow you to inspect, edit, and test the linear() points.
  • easings.net provides code for 30 naturalistic animation curves that you can copy and adapt. You can paste JavaScript functions or SVG curves into the linear() generator which creates linear() CSS code.

The linear() function allows developers to define complex animations in CSS without the need for JavaScript.

Ready to build?

Have something complicated to build?

Tell us what you are trying to achieve, not just which page template you think you need. Whether it is a bespoke web application, a complex ecommerce build, or ongoing development support — we will tell you honestly how we can help.