Анимируем linear-gradient (background-image).

При верстке, периодически необходимо создать фон, который является градиентной заливкой (картинкой или чем-то другим, нужное подчеркнуть). 
Такую задачу вполне легко сделать, используя background-image (linear-gradient в случае с градиентной заливкой).

Разберем анимирование background-image в случае работы с кнопками:

Кнопка с background-image: linear-gradient

Её CSS:

При взаимодействии с кнопкой очень желательно получать “отклик”, например, при наведении (hover) на нее. 
Один из способов организовать такой отклик — изменить background, как это сделано в разбираемом примере.

Но у нас есть один недостаток — кнопка меняет свою заливку мгновенно, переход получается слишком резким.

Установить просто transition: background не получится, так как background-image является не анимируемым свойством (www.w3schools.com/cssref/pr_background-image.asp)

Что можно сделать в таком случае, чтобы решить задачу?

Самый простой и бронебойный способ — создаем какой-нибудь элемент рядом (или внутри) с нужным нам, скрываем его, а когда наводим курсор на кнопку — отображаем с анимированием прозрачности.

С одной стороны, мы можем вкладывать в button какой-нибудь span, но это не особо удобный и масштабируемый подход. Почему подход неудобный? Представьте, что с кнопкой всегда нужно вставлять рядом span, не забывать об этом, да и для других элементов подобный подход будет доставлять неудобства. Поэтому обратимся к псевдоэлементам. Алгоритм действий в таком случае будет следующим:

  1. Создаем кнопку
  2. Задаем кнопке position: relative. Это позволит нам растягивать псевдоэлемент по размеру кнопки. Подход практически аналогичный тому, который я описывал в статье “Селекторы на любой вкус” (https://medium.com/@xnim/%D0%BD%D0%B0%D1%82%D0%B8%D0%B2%D0%BD%D1%8B%D0%B5-select-%D1%8B-%D0%BD%D0%B0-%D0%BB%D1%8E%D0%B1%D0%BE%D0%B9-%D0%B2%D0%BA%D1%83%D1%81-13c9a2a5bb36)
  3. Задаем кнопке:
    — размеры (top:0; left: 0; width: 100%; height: 100%), 
    — нужный background-image (для состояния hover) 
    — z-index: -1 (чтобы контент псевдоэлемента не скрывал наш текст
    — opacity: 0 + transition: opacity для анимаций
  4. Добавляем :hover состояние для кнопки, по которому наш псевдоэлемент будет проявляться.

Полученный результат можно посмотреть на СodePen:

Итоговый CSS:

На CodePen также можно поэкспериментировать с временем анимации :)

P.S. Я веду в телеграме небольшой канал, посвященный фронтенд-разработке. Ежедневно публикую тот или иной факт или механику из мира JS. https://t.me/FrontEndReicipes