Использование пользовательских свойств CSS для изменения анимации ключевых кадров

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

Наследование CSS-анимации

При применении анимации к элементу мы можем настроить некоторые ее свойства: длительность, задержка и т. д. Предположим, что у нас есть два класса: .walk и .run. Но .run выполняет анимацию быстрее, чем .walk (0.5 и 2 секунды).

@keyframes breath {
  from {
    transform: scale(0.5);
  }
  to {
    transform: scale(1.5);
  }
}

/* Для обоих классов задана одна и та же анимация. Но walk медленнее, чем run *
.walk {
  animation: breath 2s alternate;
}

.run {
  animation: breath 0.5s alternate;
}

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

Вернемся к нашему примеру. Класс .walk выполняет анимацию breath не только медленнее, но и масштабнее. То есть сильнее увеличивает размер элемента при анимации. Поэтому нам нужно изменить значение функции scale(), чтобы оно было больше, чем у класса .run.

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

@keyframes breath {
  /* то же, что и раньше... */
}

/* аналогично breath, но с другими значениями scale */
@keyframes breathDeep {
  from {
    transform: scale(0.3);
  }
  to {
    transform: scale(1.7);
  }
}

.walk {
  animation: breathDeep 2s alternate;
}

.run {
  animation: breath 0.5s alternate;
}

Но есть лучшее решение, которое позволяет повторно использовать как свойства анимации, так и ее значения! Для этого воспользуемся наследованием CSS-переменных:

/* breath ведет себя, соответственно
значению переменных CSS, которые наследуются */
@keyframes breath {
  from {
    transform: scale(var(--scaleStart));
  }
  to {
    transform: scale(var(--scaleEnd));
  }
}

.walk {
  --scaleStart: 0.3;
  --scaleEnd: 1.7;
  animation: breath 2s alternate;
}

.run {
  --scaleStart: 0.8;
  --scaleEnd: 1.2;
  animation: breath 0.5s alternate;
}

Благодаря этому нам не нужно повторно объявлять одну и ту же анимацию, чтобы получить от нее различные эффекты.

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

Вадим Дворниковавтор-переводчик статьи «Using Custom Properties to Wrangle Variations in Keyframe Animations»