W3docs

CSS-анимации

Изучите CSS-анимации и управление ими из JavaScript: переключайте классы, реагируйте на события transitionend, animationend и animationiteration.

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

Введение в CSS-анимации

CSS-анимации позволяют веб-разработчикам анимировать HTML-элементы без использования JavaScript. Они определяются с помощью ключевых кадров, задающих стили в различных точках последовательности анимации.

Базовый пример CSS-анимации

<div class="animated-box"></div>

<style>
  .animated-box {
    width: 100px;
    height: 100px;
    background-color: red;
    animation: move 4s infinite;
  }

  @keyframes move {
    0% { transform: translateX(0); }
    50% { transform: translateX(200px); }
    100% { transform: translateX(0); }
  }
</style>
Внимание

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

Ключевые свойства CSS-анимаций

  • animation-name: задаёт имя ключевых кадров.
  • animation-duration: определяет продолжительность анимации.
  • animation-timing-function: задаёт кривую скорости анимации.
  • animation-delay: откладывает начало анимации.
  • animation-iteration-count: определяет количество повторений анимации.
  • animation-direction: указывает, должна ли анимация воспроизводиться в обратном направлении при чередующихся циклах.

Применение нескольких анимаций

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

<div class="multi-animated-box"></div>

<style>
  .multi-animated-box {
    width: 100px;
    height: 100px;
    background-color: blue;
    animation: move 4s infinite, rotate 2s infinite;
  }

  @keyframes move {
    0% { transform: translateX(0); }
    50% { transform: translateX(200px); }
    100% { transform: translateX(0); }
  }

  @keyframes rotate {
    0% { transform: rotate(0deg); }
    100% { transform: rotate(360deg); }
  }
</style>

Продвинутые техники

Адаптивные анимации

Убедитесь, что анимации адаптируются к различным размерам экрана.

<div class="responsive-box"></div>

<style>
  .responsive-box {
    width: 50vw;
    height: 50vw;
    background-color: green;
    animation: resize 4s infinite;
  }

  @keyframes resize {
    0% { width: 50vw; height: 50vw; }
    50% { width: 70vw; height: 70vw; }
    100% { width: 50vw; height: 50vw; }
  }
</style>

Комбинирование трансформаций

Объединяйте несколько свойств трансформации для создания сложных анимаций.

<div class="complex-transform-box"></div>

<style>
  .complex-transform-box {
    width: 100px;
    height: 100px;
    background-color: yellow;
    animation: complexTransform 5s infinite;
  }

  @keyframes complexTransform {
    0% {
      transform: translateX(0) rotate(0deg) scale(1);
    }
    50% {
      transform: translateX(200px) rotate(180deg) scale(1.5);
    }
    100% {
      transform: translateX(0) rotate(360deg) scale(1);
    }
  }
</style>

Режимы заполнения анимации

Свойство animation-fill-mode определяет, как CSS-анимация применяет стили к целевому элементу до и после её выполнения.

<div class="fill-mode-box"></div>

<style>
  .fill-mode-box {
    width: 100px;
    height: 100px;
    background-color: purple;
    animation: fillMode 3s forwards;
  }

  @keyframes fillMode {
    0% { background-color: purple; }
    100% { background-color: orange; }
  }
</style>

Задержки и функции времени анимации

Используйте задержки и функции времени для управления темпом и моментом начала анимаций.

<div class="timing-function-box"></div>

<style>
  .timing-function-box {
    width: 100px;
    height: 100px;
    background-color: pink;
    animation: timingFunction 4s ease-in-out infinite;
  }

  @keyframes timingFunction {
    0% { transform: translateY(0); }
    50% { transform: translateY(200px); }
    100% { transform: translateY(0); }
  }
</style>

Лучшие практики CSS-анимаций

  1. Минимизируйте нагрузку на CPU: делайте анимации простыми, чтобы избежать избыточного использования CPU, которое может снизить производительность, особенно на мобильных устройствах.
  2. Используйте аппаратное ускорение: применяйте свойства transform и opacity, чтобы задействовать ускорение GPU.
  3. Запасные стили: предусмотрите запасные стили для браузеров, не поддерживающих анимации.
  4. Тестирование производительности: тестируйте анимации на разных устройствах и в разных браузерах для обеспечения плавной работы.
Информация

Для создания более интерактивных анимаций можно использовать JavaScript. Смотрите раздел JavaScript-анимации.

Пример хорошо оптимизированной анимации

<div class="optimized-box"></div>

<style>
  .optimized-box {
    width: 100px;
    height: 100px;
    background-color: cyan;
    animation: optimizedMove 3s ease-in-out infinite;
  }

  @keyframes optimizedMove {
    0% { transform: translateY(0) scale(1); }
    50% { transform: translateY(200px) scale(1.2); }
    100% { transform: translateY(0) scale(1); }
  }
</style>

Управление CSS-анимациями из JavaScript

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

Это позволяет сохранить плавное воспроизведение с аппаратным ускорением в CSS, пока ваш код контролирует временну́ю последовательность и последующие действия.

Запуск и остановка с помощью переключения класса

Поместите анимацию на класс вместо базового селектора, а затем переключайте этот класс:

<button id="play">Play</button>
<div id="box"></div>

<style>
  #box {
    width: 100px;
    height: 100px;
    background: teal;
  }
  /* The animation only runs while this class is present */
  #box.run {
    animation: slide 1s ease-in-out;
  }
  @keyframes slide {
    from { transform: translateX(0); }
    to   { transform: translateX(200px); }
  }
</style>

<script>
  const box = document.getElementById('box');
  document.getElementById('play').onclick = () => {
    // Toggle: add the class to play, the CSS animation does the rest
    box.classList.add('run');
  };
</script>

Поскольку анимация привязана к классу .run, удаление этого класса немедленно останавливает её, а повторное добавление запускает с начала.

Информация

Добавление и удаление классов анимации — это задача стилизации. Полный набор инструментов смотрите в разделах Стили и классы и Работа со стилями в DOM.

Отслеживание завершения: transitionend и animationend

Ключевое преимущество управления анимациями из JavaScript состоит в том, что браузер генерирует DOM-события, на которые можно реагировать. Это позволяет выстраивать цепочки шагов, очищать классы или выполнять код точно в момент завершения эффекта — без ненадёжных задержек через setTimeout.

  • Для CSS переходов событие transitionend срабатывает при завершении перехода.
  • Для CSS анимаций (@keyframes) срабатывают три события: animationstart, animationiteration (один раз за цикл) и animationend.
<button id="fade">Fade out</button>
<div id="panel">Hello</div>

<style>
  #panel {
    width: 150px;
    padding: 20px;
    background: gold;
    transition: opacity 0.5s;
  }
  #panel.hidden { opacity: 0; }
</style>

<script>
  const panel = document.getElementById('panel');

  document.getElementById('fade').onclick = () => panel.classList.add('hidden');

  // Runs the moment the fade completes — not a guessed delay
  panel.addEventListener('transitionend', (event) => {
    console.log(`Transition of "${event.propertyName}" finished`);
    panel.style.display = 'none'; // safe to hide only now
  });
</script>

После завершения перехода в консоли появится:

Transition of "opacity" finished

Чтение данных событий: propertyName и animationName

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

  • event.propertyName — CSS-свойство, для которого завершился переход (в transitionend).
  • event.animationName — имя @keyframes (в трёх событиях анимации).
  • event.elapsedTime — время выполнения в секундах, без учёта animation-delay.
<div id="bouncer">Watch the console</div>

<style>
  #bouncer { animation: bounce 0.6s ease 3; }
  @keyframes bounce {
    0%, 100% { transform: translateY(0); }
    50%      { transform: translateY(-30px); }
  }
</style>

<script>
  const el = document.getElementById('bouncer');

  el.addEventListener('animationstart', (e) =>
    console.log(`start: ${e.animationName}`));

  el.addEventListener('animationiteration', (e) =>
    console.log(`loop of ${e.animationName} at ${e.elapsedTime}s`));

  el.addEventListener('animationend', (e) =>
    console.log(`end: ${e.animationName} (total ${e.elapsedTime}s)`));
</script>

При animation: bounce 0.6s ease 3 (три итерации) в консоли появятся start, два события animationiteration (начало 2-го и 3-го циклов), затем end при суммарном времени 1.8s.

Внимание

animationiteration срабатывает между циклами, поэтому для анимации с N повторениями оно сработает N − 1 раз — никогда после последнего цикла. Используйте animationend для определения момента «всё завершено».

JS-управление vs. CSS-управление: что выбрать?

Используйте CSS-управление (keyframes/переходы), когда…Используйте JS-управление, когда…
Движение фиксировано и декларативно (наведение, загрузчики, появления).Значения зависят от данных во время выполнения (позиция перетаскивания, прокрутка, физика).
Вы хотите наилучшую производительность с минимальным кодом.Нужен покадровый контроль или возможность поставить на паузу/возобновить на полпути.
Браузер может перенести работу на GPU (transform, opacity).Нужно анимировать свойства, которые CSS не может легко выразить.

Практический гибрид — лучшее из обоих подходов: CSS описывает эффект, JavaScript решает, когда он запускается и что происходит дальше через перечисленные выше события. Когда действительно нужен покадровый контроль, обратитесь к JavaScript-анимациям с requestAnimationFrame или к Web Animations API для создания и управления анимациями полностью в коде.

Заключение

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

Практика

Практика
Какие из следующих утверждений о CSS-анимациях верны?
Какие из следующих утверждений о CSS-анимациях верны?
Was this page helpful?