CSS свойство animation-timing-function

Определение и применение

Свойство animation-timing-function определяет, как меняется прогресс между ключевыми кадрами анимации элемента: равномерно, с ускорением, замедлением или скачками. Длительность цикла при этом не меняется.

Основы и примеры — в уроке об анимациях CSS. Несколько настроек можно объединить сокращённым свойством animation.

В редакторе кривой плавности можно подобрать контрольные точки и сравнить движение с равномерным.

Попробуйте значения animation-timing-function

Меняется распределение скорости внутри прохода; steps делает движение ступенчатым.

Значение свойства

animation-timing-function: linear

HTML и CSS примера
HTML
<div class="stage">
  <div class="demo-target">CSS</div>
</div>
CSS
* {
  box-sizing: border-box;
}
.stage {
  width: 100%;
  max-width: 300px;
  height: 210px;
  display: grid;
  place-items: center;
  padding: 20px;
  border: 2px dashed #607589;
  background: #edf2f5;
  color: #172c3d;
  font: 16px/1.4 system-ui;
}
.demo-target {
  width: 100px;
  height: 80px;
  display: grid;
  place-items: center;
  border: 3px solid #245a85;
  background: #ffe4bd;
  animation-name: travel;
  animation-duration: 2s;
  animation-iteration-count: infinite;
  animation-direction: alternate;
  animation-timing-function: linear;
}
@keyframes travel {
  from {
    transform: translateX(-55px);
  }
  to {
    transform: translateX(55px);
  }
}
@keyframes turn {
  from {
    transform: rotate(-30deg);
  }
  to {
    transform: rotate(30deg);
  }
}

Поддержка браузерами

Спецификация: CSS animations

Поддерживается во всех основных браузерах с 2016 года.

Показать браузеры
Совместимостьcss.properties.animation-timing-function
ВозможностьКомпьютерыМобильные
ChromeEdgeFirefoxOperaSafariChrome AndroidFirefox for AndroidOpera AndroidSafari on iOSSamsung BrowserWebView AndroidWebView on iOS
animation-timing-function✓43✓12✓16✓30✓9✓43✓16✓30✓9✓4.0✓43✓9
ease✓3✓12✓5✓15✓4✓18✓5✓14✓3.2✓1.0✓4.4✓3.2
ease-in✓3✓12✓5✓15✓4✓18✓5✓14✓3.2✓1.0✓4.4✓3.2
ease-in-out✓3✓12✓5✓15✓4✓18✓5✓14✓3.2✓1.0✓4.4✓3.2
ease-out✓3✓12✓5✓15✓4✓18✓5✓14✓3.2✓1.0✓4.4✓3.2
jump✓77✓79✓65✓64✓14✓77✓65✓55✓14✓12.0✓77✓14
linear✓3✓12✓5✓15✓4✓18✓5✓14✓3.2✓1.0✓4.4✓3.2
step-end✓3✓12✓5✓15✓4✓18✓5✓14✓3.2✓1.0✓4.4✓3.2
step-start✓3✓12✓5✓15✓4✓18✓5✓14✓3.2✓1.0✓4.4✓3.2

поддерживаетсяс ограниченияминет поддержкинет данных≤31 — не позднее версии 31

Функция linear() новее ключевого слова linear и имеет отдельную поддержку. Проверяйте её для целевых браузеров; готовые кривые и steps() не требуют linear().

CSS синтаксис:

CSS
/* Готовые функции */
animation-timing-function: [ linear | ease | ease-in | ease-out | ease-in-out | step-start | step-end ]#;

/* Настраиваемые функции */
animation-timing-function: [ cubic-bezier(<number [0,1]>, <number>, <number [0,1]>, <number>)
  | steps(<integer [1,∞]> [ , <step-position> ]?)
  | linear( [ <number> && <percentage>{0,2} ]# ) ]#;

/* Глобальные значения */
animation-timing-function: initial | inherit | unset | revert | revert-layer;

<number> — число, [0,1] ограничивает его диапазон; <integer [1,∞]> — положительное целое. <percentage> — позиция в процентах; {0,2} означает до двух позиций. && объединяет части в любом порядке (позиции здесь необязательны), ? — необязательная часть. <step-position>: jump-start | jump-end | jump-none | jump-both | start | end. В одном списке можно смешивать готовые и настраиваемые функции. Знак # означает одно или несколько значений через запятую. Знак | разделяет варианты. Квадратные скобки группируют варианты.

JavaScript синтаксис:

JavaScript
element.style.animationTimingFunction = "ease-in-out";

Начальное значение свойства

ease.

Значения свойства

Значения animation-timing-function
Значение Описание
ease Плавный старт, ускорение и замедление к концу: cubic-bezier(0.25, 0.1, 0.25, 1). Начальное значение.
linear Равномерное изменение прогресса.
ease-in Ускорение: cubic-bezier(0.42, 0, 1, 1).
ease-out Замедление: cubic-bezier(0, 0, 0.58, 1).
ease-in-out Ускорение и замедление: cubic-bezier(0.42, 0, 0.58, 1).
cubic-bezier(x1, y1, x2, y2) Кривая по двум контрольным точкам. Только x1 и x2 ограничены диапазоном от 0 до 1; y1 и y2 могут выходить за него. Подобрать контрольные точки, сравнить движение и скопировать готовое значение можно в нашем редакторе кривой плавности.
Построение кубической кривой Безье по четырём контрольным точкам
Построение кубической кривой Безье по четырём контрольным точкам. Источник: Wikimedia Commons.
steps(n, position) Ступенчатая функция. n — положительное целое; для jump-none требуется минимум 2. jump-start/start делает скачок в начале, jump-end/end — в конце. jump-none не делает скачков на обоих краях, jump-both делает на обоих. По умолчанию jump-end.
step-start Эквивалент steps(1, jump-start).
step-end Эквивалент steps(1, jump-end).
linear(...) Кусочно-линейная функция через минимум две точки, например linear(0, 0.3 50%, 1). Числа задают выходной прогресс, проценты — входную позицию; пропущенные позиции распределяются автоматически.
initial Устанавливает начальное значение свойства.
inherit Наследует вычисленное значение свойства у родительского элемента.
unset Для ненаследуемого свойства animation-timing-function устанавливает его начальное значение.
revert Отменяет заданное в коде значение свойства для этого элемента: применяются пользовательские или стандартные стили браузера. Если они не задают значение, свойство наследуется или получает начальное значение по обычным правилам. Не возвращает значение из предыдущей строки CSS.
revert-layer Сбрасывает значение свойства для текущего слоя каскада @layer. Применяется значение из другого слоя по правилам каскада; если подходящего значения нет, возможен откат к стилям пользователя или браузера.

Значения через запятую соответствуют именам в animation-name по порядку. Если значений меньше, список повторяется; лишние значения не используются.

Функция времени в ключевом кадре

Значение внутри @keyframes действует от этого кадра до следующего кадра соответствующего свойства. На последнем кадре 100% оно не используется.

CSS
@keyframes travel {
  0% { transform: translateX(0); }
  25% { transform: translateX(40px); animation-timing-function: linear; }
  100% { transform: translateX(160px); }
}

Спецификация

CSS Animations Level 1.

CSS Easing Functions Level 2.

Наследуется

Нет.

Анимируемое

Нет.

Примеры, попробуйте сами

Равномерное движение и ускорение

Обе дорожки проходят одинаковый путь за 3s. Сравните linear и ease-in-out; замените второе значение на ease-in или ease-out.

base.css
CSS
* {
    box-sizing: border-box;
}
body {
    margin: 16px;
    font:
        16px/1.4 system-ui,
        sans-serif;
    color: #172c3d;
}
.track {
    position: relative;
    height: 70px;
    margin-top: 16px;
    border: 1px dashed #607589;
    background: #edf2f5;
}
.box {
    position: absolute;
    top: 12px;
    left: 0;
    width: 42px;
    height: 42px;
    display: grid;
    place-items: center;
    border-radius: 6px;
    background: #245a85;
    color: white;
}
.run:not(:checked) ~ .track .box {
    animation-name: none;
}
index.html
HTML
<input class="run" type="checkbox" id="run" checked />
<label for="run">Запустить анимацию</label>
<div class="track"><span class="box">A</span></div>
<div class="track second"><span class="box">B</span></div>
style.css
CSS
.box {
    animation-name: travel;
    animation-duration: 3s;
    animation-iteration-count: infinite;
    animation-direction: alternate;
    animation-timing-function: linear;
}
.second .box {
    animation-timing-function: ease-in-out;
}

/* Длина пути зависит от ширины дорожки: пример помещается на телефоне. */
@keyframes travel {
    from {
        left: 0;
        background: #a64400;
    }
    to {
        left: calc(100% - 42px);
        background: #16703c;
    }
}

Движение по шагам

Сравните плавное движение linear и четыре скачка steps(4, end). Измените число шагов или замените end на start.

base.css
CSS
* {
    box-sizing: border-box;
}
body {
    margin: 16px;
    font:
        16px/1.4 system-ui,
        sans-serif;
    color: #172c3d;
}
.track {
    position: relative;
    height: 70px;
    margin-top: 16px;
    border: 1px dashed #607589;
    background: #edf2f5;
}
.box {
    position: absolute;
    top: 12px;
    left: 0;
    width: 42px;
    height: 42px;
    display: grid;
    place-items: center;
    border-radius: 6px;
    background: #245a85;
    color: white;
}
.run:not(:checked) ~ .track .box {
    animation-name: none;
}
index.html
HTML
<input class="run" type="checkbox" id="run" checked />
<label for="run">Запустить анимацию</label>
<div class="track"><span class="box">A</span></div>
<div class="track second"><span class="box">B</span></div>
style.css
CSS
.box {
    animation-name: travel;
    animation-duration: 4s;
    animation-iteration-count: infinite;
    animation-timing-function: linear;
}
.second .box {
    animation-timing-function: steps(4, end);
}

/* Длина пути зависит от ширины дорожки: пример помещается на телефоне. */
@keyframes travel {
    from {
        left: 0;
        background: #a64400;
    }
    to {
        left: calc(100% - 42px);
        background: #16703c;
    }
}

Пользовательские функции времени

Все три блока проходят одинаковый путь за 4s. A движется равномерно, B ускоряется по cubic-bezier(), C использует linear() с паузой в середине. Измените координаты кривой B или позиции 25% и 75% у C. Функция linear() требует поддерживающего её браузера; иначе C использует резервное linear.

base.css
CSS
* {
    box-sizing: border-box;
}
body {
    margin: 16px;
    font:
        16px/1.4 system-ui,
        sans-serif;
    color: #172c3d;
}
.track {
    position: relative;
    height: 70px;
    margin-top: 16px;
    border: 1px dashed #607589;
    background: #edf2f5;
}
.box {
    position: absolute;
    top: 12px;
    left: 0;
    width: 42px;
    height: 42px;
    display: grid;
    place-items: center;
    border-radius: 6px;
    background: #245a85;
    color: white;
}
.run:not(:checked) ~ .track .box {
    animation-name: none;
}
index.html
HTML
<input class="run" type="checkbox" id="run" checked />
<label for="run">Запустить анимацию</label>
<div class="track"><span class="box">A</span></div>
<div class="track second"><span class="box">B</span></div>
<div class="track third"><span class="box">C</span></div>
style.css
CSS
.box {
    animation-name: travel;
    animation-duration: 4s;
    animation-iteration-count: infinite;
    animation-timing-function: linear;
}
.second .box {
    animation-timing-function: cubic-bezier(0.42, 0, 1, 1);
}
.third .box {
    /* Резервное linear задано общим правилом выше. */
    animation-timing-function: linear(0, 0.5 25%, 0.5 75%, 1);
}
@keyframes travel {
    from {
        left: 0;
    }
    to {
        left: calc(100% - 42px);
    }
}

Функция времени внутри ключевого кадра

A движется равномерно на обоих участках. У B функция steps(2, end), записанная в кадре 50%, действует только на вторую половину цикла. Замените её на ease-in или перенесите в кадр from: сравните, какой участок изменился. Значение на кадре 100% не задаёт следующий участок.

base.css
CSS
* {
    box-sizing: border-box;
}
body {
    margin: 16px;
    font:
        16px/1.4 system-ui,
        sans-serif;
    color: #172c3d;
}
.track {
    position: relative;
    height: 70px;
    margin-top: 16px;
    border: 1px dashed #607589;
    background: #edf2f5;
}
.box {
    position: absolute;
    top: 12px;
    left: 0;
    width: 42px;
    height: 42px;
    display: grid;
    place-items: center;
    border-radius: 6px;
    background: #245a85;
    color: white;
}
.run:not(:checked) ~ .track .box {
    animation-name: none;
}
index.html
HTML
<input class="run" type="checkbox" id="run" checked />
<label for="run">Запустить анимацию</label>
<div class="track"><span class="box">A</span></div>
<div class="track second"><span class="box">B</span></div>
style.css
CSS
.box {
    animation-duration: 4s;
    animation-iteration-count: infinite;
    animation-timing-function: linear;
    animation-name: steady;
}
.second .box {
    animation-name: segmented;
}
@keyframes steady {
    from {
        left: 0;
    }
    50% {
        left: calc(50% - 21px);
    }
    to {
        left: calc(100% - 42px);
    }
}
@keyframes segmented {
    from {
        left: 0;
    }
    50% {
        left: calc(50% - 21px);
        /* Эта функция действует от 50% до 100%. */
        animation-timing-function: steps(2, end);
    }
    to {
        left: calc(100% - 42px);
    }
}