Рассмотрим способ реализации “параметризованной” css анимации React компонента с помощью styled components. Параметризованная потому что css анимация описывается через параметры, которые динамически рассчитываются на основе пропсов и состояний компонента при его рендеринге. Идея возникла при необходимости создания анимации таймера:   Анимация цифры не представляет трудности, а вот бегущая закрашенная часть границы достаточно интересна. Длина закрашенной части границы уменьшается пропорционально тому, как таймер стремится к 0.   Если принять изначально, что таймер считает всегда 10 секунд, то написать css анимацию вполне просто. Но хочется сделать красивый универсальный компонент, в который просто можно передать количество секунд и получить красивый результат. То есть анимация должна рассчитываться в зависимости от стартового значения таймера. Для решения поставленной задачи пришла идея воспользоваться одной из основных возможностей styled components — передачей пропсов для параметризации стилей  (тут написано на сколько это круто). Создаем компонент. На вход компонент принимает только один параметр time — время сколько необходимо считать. Дальше создаем состояние компонента currentNum — текущее значение счетчика.    В useEffect прописываем обновление счетчика, в случае изменения time.   <GreyFonPopup> — просто внешний div, который закрывает всё приложение серой полупрозрачной пленкой (потому что компонент разрабатывался как pop-up).   <TimerContainer> — блок таймера на котором и происходит анимация рамки.   <NumberContainer> и вложенные в него блоки <span> служат для анимации переворачивания цифры счетчика, подробно разбираться в них не будем. Единственное, важно отметить, что на span висит анимация длительностью в секунду, поэтому событие onAnimationEnd() используется как таймер для отсчета и в нём уменьшается счетчик компонента. Для создания на основе пропсов анимации прокидываем их в TimerContainer.   Принцип создания анимации рамки иллюстрирует гифка — один элемент окрашивается и вращается, второй скрывает его середину. Подробнее можно прочитать здесь Следовательно, в нашем случае на псевдоэлементе before, работают две анимации. Первая — простое бесконечно вращение, вторая — анимация отвечающая за изменение длины закрашенной части границы (угла заливки градиента), которую необходимо рассчитывать исходя из начального и текущего значения таймера.    Для расчета и инициализации этой анимации вызываем функцию animateBorder() и передаем в неё рассчитанные на основе пропсов параметры.   360 * props.currentNum / props.time — текущая величина светящейся части контура в градусах;360 / props.time  — шаг изменения длины светящейся части контура в градусах. Функция для создания анимации animateBorder(), как уже было сказано, принимает два параметра:  deg — значение в градусах, соответствующее текущей длине окрашенной линии границы, step — шаг в градусах, на который надо изменить длину этой линии.  Сама функция создает ключевые кадры анимации и возвращает css анимацию на их основе.   Но так как градиент фона не любит анимироваться, визуально анимация будет совсем не та. Линия уменьшается не плавно, а как-будто от неё периодически откусывают кусок: Выход есть, пусть и не очень красивый. Вручную прописать промежуточные состояния. Однако если прописать порядка 10 промежуточных точек, то при счете от большого значения (то есть при малом шаге изменения длины) всё будет работать, а при счете от малых значений (большой шаг изменения длины), визуально будет выглядеть отрывисто. Если же описать много промежуточных точек, то будет выглядеть всегда плавно, но будет не рационально для анимации счета от большого числа, и код будет сильно раздут. Поэтому воспользуемся ещё одним преимуществом JS — напишем цикл. В цикле будем составлять ключевые кадры анимации, и сделаем количество точек зависящим от шага анимации.   Ну вот и красота. Мы написали css анимацию компонента, которая зависит от переданных в него параметров, и сделали это без описания кучи разных классов и анимации для них.  Код проекта с итоговой версией таймер на Github   А тут можно посмотреть на работу таймера    P.S. надеюсь данный материал поможет кому-то в создании прекрасной анимации. Если же я допустил ошибки или вы имеете своё мнение по данному подходу, с удовольствием жду вас в комментариях.   Frontend developer