W3docs

CSS transition-timing-function Property

How to use the CSS transition-timing-function longhand property to specify the speed of the transition effect. See property values and try examples.

The transition-timing-function CSS property specifies the speed curve of a transition — that is, how the intermediate values are calculated over the course of the transition's duration. It does not change how long a transition takes (that is the job of transition-duration); instead it controls the pacing in between.

Why does this matter? A transition that runs at a perfectly constant speed (linear) often looks robotic. Real-world motion accelerates and decelerates, so the default ease curve — slow start, fast middle, slow finish — feels far more natural to the eye. Choosing the right timing function is what separates a polished UI animation from a stiff one.

The transition-timing-function property is one of the CSS3 properties.

This page covers the keyword values, the powerful cubic-bezier() and steps() functions, how to set a different curve per property, and the most common pitfalls.

Keyword values

The property accepts these named curves:

  • ease — slow start, fast, slow end (the default)
  • linear — constant speed throughout
  • ease-in — slow start, speeds up toward the end
  • ease-out — fast start, slows down toward the end
  • ease-in-out — slow start and slow end, faster in the middle
  • step-start — jump to the end value immediately (no in-between)
  • step-end — hold the start value, then jump at the end

Each keyword is just shorthand for an underlying cubic-bezier() or steps() definition — for example, linear equals cubic-bezier(0, 0, 1, 1) and ease equals cubic-bezier(0.25, 0.1, 0.25, 1).

Initial Valueease
Applies toAll elements, ::before and ::after pseudo-elements.
InheritedNo.
AnimatableNo.
VersionCSS3
DOM Syntaxobject.style.transitionTimingFunction = "ease";

Syntax

CSS transition-timing-function values

transition-timing-function: linear | ease | ease-in | ease-out | ease-in-out | step-start | step-end | steps(int,start|end) | cubic-bezier(n,n,n,n)  | initial | inherit;

When a value is omitted, the browser uses the initial value ease.

Example of transition-timing-function

In the example below two properties animate together. The first timing function applies to the first transition-property (background-color), and the second applies to left. The cubic-bezier() curve here intentionally overshoots 1 so the box bounces slightly past its target — something none of the keyword values can do.

CSS transition-timing-function code example

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      .box {
        padding: 2em;
        width: 40px;
        height: 40px;
        left: 0;
        background-color: #666;
        position: relative;
        transition-property: background-color, left;
        transition-duration: 1s, 1s;
        transition-timing-function: ease-out, cubic-bezier(.75, .3, .14, 1.12);
        /* first value corresponds to the first transition-property value, and the second value corresponds to the second */
      }
      .example:hover .box {
        left: 450px;
        background-color: #ccc;
      }
    </style>
  </head>
  <body>
    <h2>Transition-timing-function property example</h2>
    <p>Hover over the element to see the effect</p>
    <div class="example">
      <div class="box"></div>
    </div>
  </body>
</html>

Example of transition-timing-function with the "ease", "linear", "ease-in" and "ease-out" values

CSS transition-timing-function values code example

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      .example {
        padding: 2em;
        width: 30px;
        height: 30px;
        left: 0;
        background-color: #666;
        border-radius: 50%;
        position: relative;
        transition-property: background-color, left;
        transition-duration: 1s, 1s;
      }
      .container:hover .example {
        left: 250px;
        background-color: #ccc;
      }
      .el1 {
        transition-timing-function: ease;
      }
      .el2 {
        transition-timing-function: linear;
      }
      .el3 {
        transition-timing-function: ease-in;
      }
      .el4 {
        transition-timing-function: ease-out;
      }
    </style>
  </head>
  <body>
    <h2>Transition-timing-function property example</h2>
    <div class="container">
      <p>
        <code>transition-timing-function: ease;</code>
      </p>
      <div class="example el1"></div>
      <p>
        <code>transition-timing-function: linear;</code>
      </p>
      <div class="example el2"></div>
      <p>
        <code>transition-timing-function: ease-in;</code>
      </p>
      <div class="example el3"></div>
      <p>
        <code>transition-timing-function: ease-out;</code>
      </p>
      <div class="example el4"></div>
    </div>
  </body>
</html>

Hover over the container and watch the four circles race: linear keeps a steady pace, ease-in lags then catches up, and ease-out shoots ahead then settles.

Example of transition-timing-function with the "step-start" and "step-end" values

CSS transition-timing-function another example

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      .example {
        padding: 2em;
        width: 30px;
        height: 30px;
        left: 0;
        background-color: #666;
        border-radius: 50%;
        position: relative;
        transition-property: background-color, left;
        transition-duration: 1s, 1s;
      }
      .container:hover .example {
        left: 250px;
        background-color: #ccc;
      }
      .el1 {
        transition-timing-function: step-start;
      }
      .el2 {
        transition-timing-function: step-end;
      }
    </style>
  </head>
  <body>
    <h2> Transition-timing-function property example</h2>
    <div class="container">
      <p>
        <code>transition-timing-function: step-start;</code>
      </p>
      <div class="example el1"></div>
      <p>
        <code>transition-timing-function: step-end;</code>
      </p>
      <div class="example el2"></div>
    </div>
  </body>
</html>

The cubic-bezier() function

Every keyword curve is built on a cubic Bézier curve, and cubic-bezier(x1, y1, x2, y2) lets you define your own. The four numbers are the coordinates of two control points; the start point (0, 0) and end point (1, 1) are fixed.

/* a gentle ease-out */
transition-timing-function: cubic-bezier(0, 0, 0.58, 1);

/* an overshoot/"bounce" — the y values can go below 0 or above 1 */
transition-timing-function: cubic-bezier(0.68, -0.55, 0.27, 1.55);

The x values (x1, x2) must stay in the range 01, but the y values may exceed it — that is exactly how you create an overshoot or anticipation effect. This is the most flexible value and is worth reaching for when the keywords feel too generic.

The steps() function

steps(n, position) makes the transition jump in n discrete steps instead of moving smoothly — useful for sprite-sheet animations, typewriter effects, or anything that should "tick" rather than glide.

/* 4 equal jumps */
transition-timing-function: steps(4, end);

The optional second argument decides whether the jump happens at the start or end of each interval (defaults to end). The keywords step-start and step-end are simply steps(1, start) and steps(1, end).

Setting a curve per property

When you transition several properties at once, you can supply a comma-separated list of timing functions. Each one lines up with the matching entry in transition-property:

transition-property: background-color, transform;
transition-duration: 0.3s, 0.6s;
transition-timing-function: ease-out, cubic-bezier(0.68, -0.55, 0.27, 1.55);

If you provide fewer timing functions than properties, the list is repeated; if you provide more, the extras are ignored.

Common pitfalls

  • It only paces, it doesn't time. A snappier-looking curve does not finish sooner — change transition-duration for that.
  • x must stay in [0, 1]. In cubic-bezier() an out-of-range x value makes the whole declaration invalid and the browser falls back to ease.
  • Order matters in lists. The Nth timing function maps to the Nth transition-property, not to a name — keep the lists aligned.
  • Prefer the transition shorthand for production code; the longhands shown here are mainly for clarity.

Values

ValueDescription
easeThe transition effect starts slowly, then becomes faster and ends slowly. This is the default value.
linearThe transition effect proceeds at a constant speed from start to finish.
ease-inThe transition effect starts slowly and accelerates toward the end.
ease-outThe transition effect starts quickly, but slows down at the end.
ease-in-outThe transition effect starts slowly and ends slowly.
step-startEquivalent to steps(1, start).
step-endEquivalent to steps(1, end).
steps(int,start|end)Specifies a stepping function with two parameters. The first parameter specifies the number of intervals in the function. It must be greater than 0. The second parameter is either the value "start" or "end", and specifies the point at which the change of values occur within the interval. If the second parameter is not applied, the value "end" is given.
cubic-bezier (n,n,n,n)Specifies a cubic Bézier curve to define the acceleration and deceleration of the transition.
initialIt makes the property use its default value.
inheritIt inherits the property from its parents element.

Practice

Practice
The transition-timing-function CSS property has the following values, except
The transition-timing-function CSS property has the following values, except
Was this page helpful?