CSS3: анимация против переходов

В CSS3 есть две техники визуализации, которые соревнуются за ваше внимание: анимация (Animations) и переходы (Transitions) (примечание: в статье будут использованы русские варианты названий этих техник). В этой статье мы попробуем выявить сходства и различия этих техник, чтобы вы понимали, когда лучше использовать тот или иной способ.

Для правильного понимания смысла данной статьи, очень желательно, чтобы вы уже имели опыт в работе с анимацией и переходами.

Сходства

Если смотреть невооруженным глазом, то кажется, что различий между анимацией и переходами нет. Обе техники позволяют:

  • определять CSS-свойства, которые мы хотим изменять;
  • устанавливать вид математической функции для управления скоростью перехода от одного значения к другому;
  • указывать продолжительность перехода или анимации;
  • перехватывать события анимации и переходов и делать с ними все, что угодно;
  • визуализировать изменения CSS-свойств.

На этом сходства заканчиваются и начинаются…

Различия

Различия между анимацией и переходами проявляются, когда вы начинаете их запускать. Различия также состоят в том, насколько легко/сложно запрограммировать переход/анимацию и тем, как легко всем этим управлять через JavaScript. Давайте исследуем эти различия более подробно.

Запуск

Одним из основных различий между переходами и анимацией является то, как они вызываются.

Переход запускается, когда изменяется какое-либо CSS-свойство. Наиболее часто встречается использование псевдокласса :hover для изменения значения свойства CSS:

В приведенном выше примере используется переход, а результатом будет расширение круга на определенную величину при наведении на него курсора мыши. Другим способом запуска перехода является использование JavaScript, чтобы программным путем добавлять или удалять CSS-классы, симулируя изменение значений свойств CSS. И, наконец, можно с помощью JavaScript задать inline-стиль меняющий CSS-свойство, которое «слушает» ваш переход.

Анимация же, в отличие от переходов, не требует явного запуска. Если анимация была определена, то она начинает работать автоматически.

С помощью имеющегося свойства, анимацию можно перевести в статус паузы (pause), что означает, что она будет неактивна до тех пор, пока свойство не будет переведено в статус запущено (running). Консорциум W3C решил удалить это свойство, поэтому сейчас его уже не существует.

Зацикливание

Это очень просто. Анимация может быть легко зациклена с помощью установки свойства animation-iteration-count. Вы можете задать любое фиксированное число для повтора анимации, которое пожелаете:

animation-iteration-count: 5;

Если вы хотите, чтобы ваша анимация повторялась бесконечно, то установите следующее значение:

animation-iteration-count: infinite;

Переходы, с другой стороны, не имеют свойства, которое определяет количество повторов. После запуска, переход повторяется только один раз. Вы можете зациклить переход с помощью события transitionEnd, но по сравнению с анимацией это далеко не так просто.

Определение промежуточных точек / ключевых кадров (keyframes)

С помощью анимации вы можете определить ключевые кадры, которые дадут вам больше контроля над значениями CSS-свойств, нежели просто начальная и конечная точка:

Вы можете задать любое количество ключевых кадров. В процессе воспроизведения анимации, каждый кадр будет изменять нужным образом значения свойств. Это позволяет вам реализовывать разнообразные виды анимации, которые позволяют HTML5 соревноваться наравне с такими анимационными технологиями, как Flash, и даже быть эффективнее.

При использовании переходов у вас нет достаточного контроля над конечным результатом:

Переход происходит из начальной точки в конечную. Вы не можете определить промежуточные точки, как в случае с анимацией, поэтому переход может быть не слишком удачным выбором, если вы хотите сложную анимацию, вроде вот этой.

Явное определение анимируемых свойств

Следующая вещь, о которой я хочу рассказать, это явное определение анимации и переходов применительно к значениям CSS-свойств.

С формальной точки зрения, если у вас есть переход, то каждое CSS-свойство, которое вы хотите с помощью него анимировать, должно быть явно определено.

Например, у вас есть следующий переход:

#mainContent { 
    background-color: #CC0000; 
    transition:background-color .5s ease-in; 
} 
#mainContent:hover { 
    cursor: pointer; 
    background-color: #000000; 
    width:500px;
}

В коде выше, указаны различные значения свойств background-color и width. Однако, явно определен переход только для свойства background-color. Это значит, что браузер будет анимировать только изменение свойства background-color.

Если же необходимо, чтобы анимированы были оба свойства — и background-color, и width — следует это явно определить:

#mainContent { 
    background-color: #CC0000;
    transition:background-color .5s ease-in, width .5s ease-in
} 
#mainContent:hover { 
    cursor: pointer; 
    background-color: #000000; 
    width: 500px;
}

Что насчет параметра «all» при определении перехода?

В действительности, нет необходимости определять каждое анимируемое свойство при объявлении перехода. Вы можете облегчить себе жизнь, если будете использовать значение «all» вместо описания конкретных свойств, например: transition: all .5s ease-in. Однако так поступать не рекомендуется, потому что такой подход наносит ущерб производительности.

В этом случае браузер наблюдает за всеми свойствами, которые могут быть анимированы, вместо того, чтобы следить за явно указанными. Если у вас нет необходимости в использовании параметра «all», то рекомендуется указывать все анимируемые свойства по отдельности.

Используя анимацию, вы можете определять промежуточные значения свойств с помощью ключевых кадров так, как вам это заблагорассудится:

keyframes imageSlide { 
    0% { 
        left: -150px;
    } 
 
    20% { 
        left: 50px; 
        height: 200px;
    } 
 
    80% { 
        left: 200px; 
        height:300px;
    } 
 
    100% { 
        left: 600px; 
        background-color:#FFFFFF;
    } 
}

В примере выше, свойства height и background-color будут плавно изменяться в соответствии с определенными ключевыми кадрами, даже если какое-то свойство до этого не было объявлено!

Взаимодействие с JavaScript

В большинстве случаев, переходы и анимация достаточно хорошо выполняют свои задачи. Вы определяете начальную и конечную, а также промежуточные точки, значения которых должны принимать CSS-свойства. Ваша анимация или переход будет считывать эти значения и заботится о том, чтобы все было точно выполнено согласно инструкциям.

Этот сценарий лучше всего работает, когда вы точно знаете, какого результата хотите достичь. Однако, может случиться так, что вам потребуется изменять значения, используемые для анимации, согласно какому-то внешнему источнику — к примеру клику мыши, результату внешнего вычисления и тому подобное.

Для такого взаимодействия не подходят величины, заранее определенные в CSS. Можно положиться на использование JavaScript, но полностью реализовывать анимацию на нем, задача достаточно сложная. Наиболее оптимальным решением в данной ситуации будет использование гибридного подхода. Это означает, что анимация или переход объявляются средствами CSS, но некоторые аспекты динамически изменяются посредством JavaScript.

Когда дело доходит до взаимодействия JavaScript и анимации/переходов, то вы почти всегда будете использовать именно переходы. При связке анимация-JavaScript… практически невозможно заставить анимацию нормально работать.

Анимация очень специфична для создания связки с JavaScript. Команда @keyframes четко определяет последовательность анимации, которая запускается сразу после загрузки страницы. Попытка изменить заданную анимацию через JavaScript потребует выполнения очень сложной последовательности шагов, включая модификацию самого стилевого правила @keyframes. Если вы когда-нибудь пытались изменять CSS-свойства внутри стилевого правила, то вы, скорее всего, представляете сложность данной процедуры.

Противоположностью анимации в данном смысле является переход. Переходы не настолько четко определены. Переход запускается, когда определенное свойство изменяется. Изменение этого свойства может быть полностью задано через CSS:

#myElement {
    background-color: #FFF;
    transition: background-color .2s ease-in;
}
#myElement:hover {
    background-color: #000;
}

Это изменение может быть выполнено через JavaScript: вы можете изменить CSS-свойство, которое «слушает» ваш переход, обратившись к inline-стилю:

var myElement = document.querySelector("#myElement");
myElement.style.backgroundColor = "333";

Переход не обращает внимания на то, каким способом изменяются значения «слушаемых» свойств. Пока значение изменяется, переход будет работать. Это значит, что вы можете делать много интересных вещей с интерактивными сценариями, не связанными жестко заданными начальными и конечными точками. Желаемые значения свойств для перехода могут быть заданы через JavaScript.

Чтобы лучше понять, о чем идет речь, посмотрите вот этот простой пример:

Кликните в любой точке серой формы и круг переместится в эту точку.

Этот пример работает достаточно просто. Перемещение круга обрабатывается с помощью CSS-перехода. Однако, координаты точки, в которую надо переместить круг, передаются через JavaScript. Так как переход «слушает» координаты, то любое их изменение ведет к запуску этого перехода. Конечный результат работы именно такой, каким он и был задуман.

Самое примечательное, что не требуется писать JavaScript-код для реализации самого перехода. И, наконец, так как поддержка переходов встроена в стандарт CSS и, соответственно, в браузер, анимация происходит очень плавно.

Эта дружба между переходами и JavaScript очень сильна, поэтому вам стоит использовать это преимущество на полную катушку.

Заключение

Теперь вы имеете достаточное представление о сходствах и различиях переходов и анимации в CSS. Вот обобщение касательно того, в каких случаях какой способ лучше применять:

  • Если требуется гибкость, обеспечиваемая, ключевыми кадрами и простотой зацикливания, то предпочтительно использовать анимацию;
  • Если нужна простая анимация из начальной точки в конечную, то следует использовать переходы;
  • Если необходимо манипулировать значением свойств в соответствии с внешними воздействиями или вычислениями, то идеально использование связки переход + JavaScript.

Конечно, имя терпение и хорошее знание JavaScript, можно нейтрализовать различия между переходами и анимацией.

Рекомендации, приведенные в данной статье, основываются на типичных случаях использования переходов и анимации. Огромные усилия, направленные на то, чтобы изменить поведение этих двух способов анимации, почетны, но не оправданы. Поэтому проще использовать все по своему назначению.

Перевод статьи «CSS3: Animations vs. Transitions» был подготовлен дружной командой проекта Сайтостроение от А до Я.