Функции плавности: transition-timing-function

transition-timing-function задаёт, с какой скоростью проходит переход - равномерно или с ускорением и замедлением. По умолчанию используется ease: переход стартует быстро и плавно тормозит к концу. Кроме готовых кривых есть ступенчатая steps() для эффекта прыжков и полностью свои кривые через cubic-bezier().

Попробуй прямо сейчас: наведи курсор на весь блок целиком - все три шарика стартуют одновременно и проезжают одинаковое расстояние, но с разными кривыми: верхний (linear) едет равномерно, средний (ease) быстро стартует и плавно тормозит, а нижний (steps) скачет резкими прыжками. Замени steps(6, jump-end) на steps(3, jump-start) и посмотри на разницу.

Готовые кривые: ease, linear, ease-in, ease-out

У каждой встроенной кривой своё ощущение движения. В переходе длительностью 1 секунда к ровно половине времени элемент по факту проходит: linear - около 48% пути (действительно равномерно), ease (значение по умолчанию) - уже около 78% (основной рывок происходит в начале, а концовка плавно тормозит), ease-in - только около 30% (стартует медленно, разгоняется к концу), ease-out - около 67% (стартует быстро, к концу замедляется, но мягче, чем ease). ease-in-out ведёт себя симметрично: медленный старт и такой же медленный финиш.

.box { transition: transform 1s ease-out; } .box:hover { transform: translateX(200px); } - ease-out: быстрый старт и мягкое торможение в конце, ощущается как естественное движение по инерции.

Неправильное ожидание - что ease-in-out используется по умолчанию, если ничего не указывать:

.box { transition: transform 1s; } - по умолчанию применяется именно ease, а не ease-in-out - это разные кривые с разным распределением скорости.

Ступенчатая анимация: функция steps()

steps(N, позиция) делит переход не на плавную кривую, а на N резких скачков - классический приём для спрайт-анимаций и эффекта печатной машинки. Позиция определяет, КОГДА происходит скачок внутри каждого отрезка: у jump-end (значение по умолчанию) элемент держит начальное значение до первой границы интервала и прыгает только по её достижении - последний прыжок происходит ровно в момент завершения перехода. У jump-start всё наоборот: первый прыжок происходит мгновенно, в самый момент запуска перехода, ещё до того, как прошло хоть какое-то время. Есть ещё jump-none (прыжков на единицу меньше, финальное значение внутри самой анимации не достигается) и jump-both (прыжков на единицу больше - есть скачок и в начале, и в конце) - более редкие частные случаи.

.sprite { transition: transform 2s steps(5, jump-end); } .sprite:hover { transform: translateX(200px); } - пять чётких скачков, первый - только после того, как пройдёт 1/5 времени.

Неправильное ожидание - что jump-start и jump-end выглядят одинаково, раз "количество шагов то же самое":

.sprite { transition: transform 2s steps(5, jump-start); } - с jump-start первый скачок происходит сразу же, в момент наведения курсора, а не после паузы - на глаз это заметно более резкий, "уже начавшийся" эффект.

Свои кривые: cubic-bezier()

cubic-bezier(x1, y1, x2, y2) описывает кривую двумя контрольными точками и позволяет задать любую скорость, которой нет среди готовых ключевых слов. У координат X (x1 и x2) есть жёсткое ограничение - только от 0 до 1, потому что они означают течение времени, которое не может идти вспять. А вот координаты Y можно выводить далеко за пределы 0-1: именно так получают эффект отскока (bounce) или лёгкого "перелёта" за целевое значение с последующим возвратом - на практике элемент реально на мгновение проезжает дальше цели, а затем плавно возвращается на своё место. Сами готовые ключевые слова - это просто именованные частные случаи cubic-bezier: ease равен cubic-bezier(.25, .1, .25, 1), а linear - cubic-bezier(0, 0, 1, 1).

.box { transition: transform .8s cubic-bezier(.34, 1.56, .64, 1); } - валидно: Y-координата 1.56 выходит за пределы 0-1, элемент на мгновение "перелетит" целевое положение и плавно вернётся - получается эффект отскока.

Неправильное ожидание - что так же свободно можно выходить за пределы и по оси X:

.box { transition: transform .8s cubic-bezier(-0.5, 0, 1.5, 1); } - X-координаты -0.5 и 1.5 вне диапазона 0-1, всё значение невалидно, и transition-timing-function просто не применится.

Частые ошибки новичков

ОшибкаЧто происходитКак исправить
Думать, что ease-in-out - это значение по умолчанию По умолчанию применяется именно ease - это другая кривая, с другим распределением скорости движения Указывать нужную кривую явно, а не полагаться на предположения о значении по умолчанию
Ждать, что jump-start и jump-end выглядят одинаково jump-start прыгает мгновенно в начале перехода, jump-end держит начальное значение до первой границы - на глаз это разные по ощущению анимации Выбирать позицию исходя из желаемого эффекта, проверяя результат вживую
Указать в cubic-bezier() X-координату вне диапазона 0-1 Значение целиком невалидно и отбрасывается - браузер применит предыдущую или дефолтную функцию плавности Держать x1 и x2 строго в пределах 0-1; выходить за границы можно только по Y
Использовать эффект отскока (Y вне 0-1) на layout-свойствах вроде width/height в контейнере с overflow: hidden Элемент временно "перелетает" целевое значение, из-за чего может обрезаться контент или дёрнуться скролл Применять отскок к transform (не влияет на раскладку страницы), а не к layout-свойствам

Шпаргалка

ЗначениеЧто означает
ease (по умолчанию)cubic-bezier(.25, .1, .25, 1) - быстрый старт, плавное торможение
linearcubic-bezier(0, 0, 1, 1) - равномерно, без ускорения и замедления
ease-in / ease-outМедленный старт с разгоном / быстрый старт с плавным финишем
steps(N, jump-end)N резких скачков; старт держится до первой границы (позиция по умолчанию)
steps(N, jump-start)Первый скачок происходит мгновенно в момент запуска перехода
cubic-bezier(x1,y1,x2,y2)Свои кривые; x1/x2 только 0...1, y1/y2 можно выводить за пределы ради эффекта отскока

Коротко: отвечаем на вопросы

В чём разница между ease, ease-in и ease-out?

ease (значение по умолчанию) быстро стартует и плавно тормозит к концу. ease-in стартует медленно и разгоняется к финалу - используется, когда элемент как будто "убегает" со страницы. ease-out - зеркальная ситуация: быстрый старт и мягкое торможение, обычно для элементов, которые "прибывают" на экран.

Можно ли сделать анимацию с эффектом отскока (bounce) на чистом CSS?

Да, без единой строчки JavaScript: достаточно указать в cubic-bezier() Y-координату больше 1 или меньше 0, например cubic-bezier(.34, 1.56, .64, 1). Элемент на мгновение проедет дальше целевого значения и плавно вернётся обратно - именно так и выглядит "пружинящий" отскок.

Есть ли инструмент, чтобы подобрать кривую cubic-bezier() визуально, а не на глаз?

Да, самый известный - cubic-bezier.com (сделан Лией Веру, соавтором нескольких CSS-спецификаций): там можно перетаскивать контрольные точки мышкой и сразу видеть, как меняется движение, а потом скопировать готовое значение в свой CSS.

Категория
Поделиться в социальных сетях

Отправить комментарий

0 Комментарии

Отправить комментарий (0)

#buttons=(Хорошо) #days=(20)

Мы используем файлы cookie для улучшения работы сайта. Подробнее
Хорошо
×