Motion

transition-timing-function

Controlling how a transition progresses through time.

Overview

ClassDeclarations
transition-timing-function-smoothtransition-timing-function: var(--easing-smooth);
transition-timing-function-softtransition-timing-function: var(--easing-soft);
transition-timing-function-crisptransition-timing-function: var(--easing-crisp);
transition-timing-function-snaptransition-timing-function: var(--easing-snap);
transition-timing-function-acceleratetransition-timing-function: var(--easing-accelerate);
transition-timing-function-deceleratetransition-timing-function: var(--easing-decelerate);
transition-timing-function-overshoottransition-timing-function: var(--easing-overshoot);
transition-timing-function-rewindtransition-timing-function: var(--easing-rewind);
transition-timing-function-springtransition-timing-function: var(--easing-spring);
transition-timing-function:easetransition-timing-function: ease;
transition-timing-function:ease-intransition-timing-function: ease-in;
transition-timing-function:ease-outtransition-timing-function: ease-out;
transition-timing-function:ease-in-outtransition-timing-function: ease-in-out;
transition-timing-function:lineartransition-timing-function: linear;
transition-timing-function:step-starttransition-timing-function: step-start;
transition-timing-function:step-endtransition-timing-function: step-end;
transition-timing-function:<function>,<…>transition-timing-function: <function>,<…>;
transition-timing-function:steps(<stop>,<direction>)transition-timing-function: steps(<stop>,<direction>);
transition-timing-function:cubic-bezier(<value>,<value>,<value>,<value>)transition-timing-function: cubic-bezier(<value>,<value>,<value>,<value>);

Examples

Choose an easing curve

Toggle each layer to compare linear, ease-in and ease-out over the same 800ms and 96px. The endpoints and total duration stay identical.

Choose an easing curve
transition-timing-function: Choose an easing curve controls
The native transition keeps its authored duration and endpoints. Compare how the curve distributes progress, or how steps advances at discrete boundaries.
<!-- Linear · constant progress --><label class="block w:280px max-w:100% font-sm         transform:translateX(96px):has(input:checked)>span>span@screen">  <input type="checkbox" aria-label="Move layer"    class="mr-xs accent-color-blue           outline:2px|solid|var(--color-blue):focus-visible           outline-offset:3px:focus-visible">  Move layer  <span aria-hidden="true"    class="block h:64px mt-md p-xs           outline:1px|dashed|var(--color-line-muted)">    <span id="target"      class="grid place-items:center h:48px w:128px             b:1px|solid|var(--color-blue-60) r-sm font-sm bg-blue-10             fg-blue-80 opacity:1 transform:none             transition-property:transform             transition-timing-function:linear             transition:none@print             transition-duration-slowest@screen@motion">      Layer 01    </span>  </span></label>
<!-- Ease in · slower at the beginning --><label class="block w:280px max-w:100% font-sm         transform:translateX(96px):has(input:checked)>span>span@screen">  <input type="checkbox" aria-label="Move layer"    class="mr-xs accent-color-blue           outline:2px|solid|var(--color-blue):focus-visible           outline-offset:3px:focus-visible">  Move layer  <span aria-hidden="true"    class="block h:64px mt-md p-xs           outline:1px|dashed|var(--color-line-muted)">    <span id="target"      class="grid place-items:center h:48px w:128px             b:1px|solid|var(--color-blue-60) r-sm font-sm bg-blue-10             fg-blue-80 opacity:1 transform:none             transition-property:transform             transition-timing-function:ease-in             transition:none@print             transition-duration-slowest@screen@motion">      Layer 01    </span>  </span></label>
<!-- Ease out · slower at the end --><label class="block w:280px max-w:100% font-sm         transform:translateX(96px):has(input:checked)>span>span@screen">  <input type="checkbox" aria-label="Move layer"    class="mr-xs accent-color-blue           outline:2px|solid|var(--color-blue):focus-visible           outline-offset:3px:focus-visible">  Move layer  <span aria-hidden="true"    class="block h:64px mt-md p-xs           outline:1px|dashed|var(--color-line-muted)">    <span id="target"      class="grid place-items:center h:48px w:128px             b:1px|solid|var(--color-blue-60) r-sm font-sm bg-blue-10             fg-blue-80 opacity:1 transform:none             transition-property:transform             transition-timing-function:ease-out             transition:none@print             transition-duration-slowest@screen@motion">      Layer 01    </span>  </span></label>
Generated CSS
@layer utilities {  .transition-timing-function\:ease-out {    transition-timing-function: ease-out  }}

An easing function maps elapsed progress to the interpolated value. It changes the distribution of movement through time, not the declared duration or destination.

Use linear timing for continuous motion

Compare steady movement with four discrete steps. Both travel 96px over one second; steps(4,end) waits until each step boundary before advancing.

Use linear timing for continuous motion
transition-timing-function: Use linear timing for continuous motion controls
The native transition keeps its authored duration and endpoints. Compare how the curve distributes progress, or how steps advances at discrete boundaries.
<!-- Linear · continuous progress --><label class="block w:280px max-w:100% font-sm         transform:translateX(96px):has(input:checked)>span>span@screen">  <input type="checkbox" aria-label="Move layer"    class="mr-xs accent-color-blue           outline:2px|solid|var(--color-blue):focus-visible           outline-offset:3px:focus-visible">  Move layer  <span aria-hidden="true"    class="block h:64px mt-md p-xs           outline:1px|dashed|var(--color-line-muted)">    <span id="target"      class="grid place-items:center h:48px w:128px             b:1px|solid|var(--color-blue-60) r-sm font-sm bg-blue-10             fg-blue-80 opacity:1 transform:none             transition:none@print             transition:transform|1s|linear@screen@motion">      Layer 01    </span>  </span></label>
<!-- Four steps · 24px per step --><label class="block w:280px max-w:100% font-sm         transform:translateX(96px):has(input:checked)>span>span@screen">  <input type="checkbox" aria-label="Move layer"    class="mr-xs accent-color-blue           outline:2px|solid|var(--color-blue):focus-visible           outline-offset:3px:focus-visible">  Move layer  <span aria-hidden="true"    class="block h:64px mt-md p-xs           outline:1px|dashed|var(--color-line-muted)">    <span id="target"      class="grid place-items:center h:48px w:128px             b:1px|solid|var(--color-blue-60) r-sm font-sm bg-blue-10             fg-blue-80 opacity:1 transform:none             transition:none@print             transition:transform|1s|steps(4,end)@screen@motion">      Layer 01    </span>  </span></label>

Linear timing gives constant progress between these numeric endpoints. Steps creates intentional jumps. Use steps() for stepped timing; it is distinct from a continuously interpolated curve.

Keep entrance and exit curves intentional

Check to move the layer out with ease-out. After it arrives, uncheck to return with ease-in. Each direction keeps the same duration.

Keep entrance and exit curves intentional
transition-timing-function: Keep entrance and exit curves intentional controls
The native transition keeps its authored duration and endpoints. Compare how the curve distributes progress, or how steps advances at discrete boundaries.
<!-- Ease out → ease in on return --><label  class="block w:280px max-w:100% font-sm         transform:translateX(96px):has(input:checked)>span>span@screen         transition-timing-function:ease-out:has(input:checked)>span>span@screen">  <input type="checkbox" aria-label="Move layer"    class="mr-xs accent-color-blue           outline:2px|solid|var(--color-blue):focus-visible           outline-offset:3px:focus-visible">  Move layer  <span aria-hidden="true"    class="block h:64px mt-md p-xs           outline:1px|dashed|var(--color-line-muted)">    <span id="target"      class="grid place-items:center h:48px w:128px             b:1px|solid|var(--color-blue-60) r-sm font-sm bg-blue-10             fg-blue-80 opacity:1 transform:none             transition:none@print             transition:transform|var(--duration-slowest)|ease-in@screen@motion">      Layer 01    </span>  </span></label>

A transition uses the timing function selected for its new state. The checked rule supplies ease-out for the outward move, and the resting rule supplies ease-in for the return. Reversing an unfinished transition can shorten its return interval.

Apply conditionally

Resize before toggling. Below sm, the layer uses ease-out; at sm, it uses linear timing. Duration and distance remain fixed.

Apply conditionally
transition-timing-function: Apply conditionally controls
The native transition keeps its authored duration and endpoints. Compare how the curve distributes progress, or how steps advances at discrete boundaries.
<!-- Ease out → linear at sm --><label class="block w:280px max-w:100% font-sm         transform:translateX(96px):has(input:checked)>span>span@screen">  <input type="checkbox" aria-label="Move layer"    class="mr-xs accent-color-blue           outline:2px|solid|var(--color-blue):focus-visible           outline-offset:3px:focus-visible">  Move layer  <span aria-hidden="true"    class="block h:64px mt-md p-xs           outline:1px|dashed|var(--color-line-muted)">    <span id="target"      class="grid place-items:center h:48px w:128px             b:1px|solid|var(--color-blue-60) r-sm font-sm bg-blue-10             fg-blue-80 opacity:1 transform:none             transition:none@print             transition:transform|var(--duration-slowest)|ease-out@screen@motion             transition-timing-function:linear@screen@sm">      Layer 01    </span>  </span></label>

The easing value follows the real iframe viewport. Reduced motion and print remove the interpolation, so a reported curve does not imply visible motion when the duration is zero.



© 2026 Aoyue Design LLC.MIT License
Trademark Policy