Практика: создание CSS-анимации
Добро пожаловать на заключительный урок данного раздела! Сегодня мы будем применять полученные знания на практике, а именно учиться трансформировать элементы, связывать эти трансформации с анимацией и создавать красивые эффекты, пользуясь возможностями CSS3.
Задание
Помните нашу предыдущую практику, где мы создавали веб-страничку для музыкальной группы? Мы останемся верны этой тематике и создадим интерактивную карту с отметками, в каких городах музыкальная группа планирует проводить концерт. При наведении курсора на точку города будет появляться выноска с датой мероприятия и кнопкой «Купить билеты»:
Загрузка файлов
Вам понадобятся определенные файлы для выполнения задания. Скачайте архив на компьютер и ознакомьтесь с его содержимым. Чтобы не тратить время на написание кода, который не относится напрямую к теме этого урока, мы заранее подготовили для вас HTML-разметку и базовые стили CSS. Вам понадобится добавить только те стили, которые будут касаться анимированных объектов.
План работы
- Для четырех точек на карте (города, в которых будут проходить концерты) создать пульсирующую анимацию для привлечения внимания.
- При наведении курсора на точку города анимация должна становиться на паузу. Когда курсор убран, анимация возобновляется.
- Также при наведении курсора на точку города должна плавно появляться небольшая выноска с местом и датой концерта, кнопкой для покупки билетов. Когда курсор убран, информационная выноска исчезает.
- Цвет кнопки в выноске должен меняться при наведении курсора.
Примечание: в целях экономии места мы не записываем в обучающем уроке префиксы производителей. Но помните, что на реальных проектах их нужно использовать.
1. Анимация для отметок на карте
Откройте в браузере веб-страницу из скачанного архива. Перед вами блок с картой, на которой нанесено четыре отметки с названиями городов. Наша задача — создать эффект расходящихся волн вокруг каждой точки. Мы сделаем две волны, в роли которых будут выступать псевдоэлементы :before
и :after
:
Псевдоэлементы удобно использовать, когда требуется добавить какое-то украшение к основному элементу. Это избавляет от необходимости добавлять лишний HTML-код, который не несет особого смысла.
Откройте в редакторе кода документ style.css
из папки css
. В течение урока мы будем соблюдать порядок в таблице стилей, добавляя новые правила не просто в конец документа, а размещая их там, где это будет логично. Поэтому найдите селектор .pin .popover
и добавьте над ним следующие стили для псевдоэлементов элемента .pin
:
.pin:before, .pin:after { content: ''; position: absolute; left: 50%; top: 50%; display: block; border-radius: 50%; border: 1px solid #f3244a; width: 0; height: 0; margin-left: -2px; margin-top: -2px; }
Мы не добавляем никакой контент к этим псевдоэлементам, а только создаем пустой блок с рамкой и скругленными углами, чтобы в итоге получить кольцо.
В начальном виде ширина и высота псевдоэлементов равна нулю. И с помощью анимации мы увеличим их размеры, чтобы создать эффект расходящихся волн. Для этого понадобится создать ключевые кадры для каждой волны.
Найдите в начале таблицы стилей комментарий /* Keyframes */
и запишите под ним два следующих правила @keyframes
:
@keyframes pinBeforeWave { from { width: 0; height: 0; margin-left: -2px; margin-top: -2px; } to { width: 40px; height: 40px; margin-left: -21px; margin-top: -21px; opacity: 0; } } @keyframes pinAfterWave { from { width: 0; height: 0; margin-left: -2px; margin-top: -2px; } to { width: 66px; height: 66px; margin-left: -34px; margin-top: -34px; opacity: 0; } }
Обе анимации имеют одинаковое начало, но отличаются окончанием. Анимацию pinBeforeWave
мы применим к псевдоэлементу :before
, и в процессе ее выполнения он увеличится до размеров 40×40 пикселей (маленькая волна). Анимация pinAfterWave
предназначена для псевдоэлемента :after
, к концу которой он примет размеры 66×66 пикселей (большая волна).
Кроме этого, в обеих анимациях предусмотрено смещение элементов на определенное количество пикселей влево и вверх — это нужно для того, чтобы при увеличении кольца отметка города визуально оставалась в его центре. И, наконец, свойство opacity
в последнем ключевом кадре означает то, что обе волны будут плавно исчезать в процессе своего расширения.
Давайте применим созданные анимации к псевдоэлементам. Для этого добавьте следующий код, разместив его следом под стилем для селектора .pin:before, .pin:after
:
.pin:before { animation: pinBeforeWave 1s ease-in infinite; } .pin:after { animation: pinAfterWave 1s ease-in infinite; }
Обе анимации будут длиться одну секунду. Распределение скорости анимации в течение этой секунды будет происходить по функции ease-in. Анимация будет повторяться бесконечно.
Сохраните изменения в таблице стилей и обновите страницу в браузере. Анимация вокруг отметок уже работает, и нам пора переходить к следующему пункту плана.
2. Пауза анимации при наведении курсора
Когда пользователь наводит курсор на элемент .pin
, анимация псевдоэлементов должна становиться на паузу. CSS позволяет применять стили к дочерним элементам, когда на их родителя наведен курсор. То же самое работает и с псевдоэлементами. Добавьте этот стиль под предыдущим:
.pin:hover:before, .pin:hover:after { animation-play-state: paused; }
Данный код говорит: когда на элемент .pin
наведен курсор (состояние :hover
), нужно поставить на паузу анимацию псевдоэлементов :before
и :after
.
3. Появление выноски
При наведении курсора на отметку должно происходить еще одно действие, а именно появление выноски с информацией о концерте. В изначальном состоянии все выноски скрыты от глаз посетителя с помощью свойств visibility: hidden
и opacity: 0
.
Найдите в файле CSS селектор .pin .popover:before
и добавьте следом за ним следующий стиль:
.pin:hover .popover { visibility: visible; opacity: 1; }
У вас мог возникнуть вопрос, зачем мы скрыли выноску сразу двумя способами. Дело в том, что использования лишь одного из этих свойств будет недостаточно. Если убрать свойство visibility
и оставить только opacity: 0
, то элемент не будет по-настоящему скрыт: да, он не будет виден для глаз, но его увидит скринридер, что иногда может мешать.
Если же убрать свойство прозрачности и оставить только visibility: hidden
, то мы не сможем добиться плавности при появлении элемента, поскольку свойство transition не действует на свойство visibility
. Именно поэтому мы использовали сразу два свойства для скрытия выноски.
Кстати о плавности. Если вы сейчас обновите страницу и наведете курсор на точку, то увидите, что выноска появляется, но делает это резко. Настало время обратиться к свойству transition
. Найдите селектор .pin .popover
и добавьте к нему такую строку:
transition: all 0.2s ease-in-out;
Теперь выноска появляется плавно: свойство opacity
переходит от значения 0
к значению 1
за 200 миллисекунд, а скорость движения анимации соответствует функции ease-in-out.
Идем дальше. Когда мы рассказывали о свойстве transition-delay
, то упоминали о том, что его удобно применять для небольшой задержки выпадающего меню перед его исчезновением, чтобы пользователь успевал навести курсор на ссылку меню. Не лишним будет применить этот эффект и для выноски, чтобы она исчезала с легкой задержкой. Для этого добавьте еще одно значение к свойству transition
для селектора .pin .popover
— 0.5s
перед точкой с запятой:
transition: all 0.2s ease-in-out 0.5s;
Но это еще не всё. Сейчас задержка появления выноски срабатывает в обоих направлениях — когда курсор наводится и когда отводится. Чтобы оставить задержку только для второго случая, допишите следующую строку к селектору .pin:hover .popover
:
transition-delay: 0s;
Сохраните изменения и обновите страницу в браузере. Теперь всё работает правильно: выноска появляется плавно и без задержки, а исчезает так же плавно, но с задержкой в полсекунды.
Нам осталось поработать еще над одной деталью. На этот раз мы вспомним свойство transform
и его функцию вращения rotate
, чтобы добавить еще один визуальный эффект при появлении выноски. Она будет словно разворачиваться лицом к зрителю в процессе появления, а затем так же исчезать.
В состоянии невидимости выноска будет развернута на 90 градусов по оси Y. Допишите следующий стиль к селектору .pin .popover
:
transform: rotateY(90deg);
При наведении курсора на точку города выноска должна возвращаться в свое нормальное положение. Для этого добавьте строку ниже к стилю для селектора .pin:hover .popover
:
transform: rotateY(0deg);
Сохранитесь и обновите веб-страницу. Понаблюдайте теперь за поведением выносок: они появляются плавно и с эффектом разворота, напоминая карточки.
4. Цвет кнопки в выноске
Последний пункт плана — плавное изменение цвета кнопки в выноске при наведении курсора на нее. Для начала создадим стиль для кнопки в состоянии :hover
. Найдите селектор .pin .popover .button
и запишите под ним следующий код:
.pin .popover .button:hover { background-color: #e10087; }
И, наконец, чтобы переход от начального цвета к конечному происходил плавно, добавьте эту строку к стилю селектора .pin .popover .button
:
transition: all 0.2s ease-in-out;
Снова сохраните изменения и полюбуйтесь результатом.
Завершение
Поздравляем! Вы полностью прошли еще один раздел учебника и создали интерактивную карту. Как и всегда, в случае каких-либо проблем вы можете посмотреть готовый рабочий код, который лежит в архиве вместе с другими файлами. А вот и демо нашего урока:
Рекомендуем вам дополнительно потренироваться в использовании CSS-анимации: придумайте альтернативные эффекты и трансформации для выносок и отметок либо попробуйте создать анимацию на других веб-страницах. Как видите, это очень увлекательная тема!
Когда вы будете готовы, приглашаем перейти к следующему разделу нашей книги, который посвящен стилизации таблиц и веб-форм. В первом уроке мы поговорим о том, как писать CSS для HTML-таблиц.