Привет, друзья. В прошлой статье обещал рассказать о том, как сделать пульсирующую кнопку в углу экрана, аналогичную тем, которые вы могли видеть у разных виджетов обратного звонка. Меня несколько раз просили рассказать как это сделать и уже на 3 сайта в этом году поставил подобную кнопку. Чтобы не писать раз за разом код заново, решил оформить все в виде статьи и просто копировать исходник отсюда. Если вы искали статью о том, как реализовать пульсирующую кнопку, то вы попали по адресу.
Вот, что мы хотим получить в итоге.

Итак, давайте начнем с разметки.
HTML разметка пульсирующей кнопки
Обычно я использую несложную структуру, которую разберем ниже. Например, я применял ее в виджете SmartLid, который планирую в этом году обновить и переписать, скорее всего на Vue.
<button class="pulse-button"> <span class="pulse-button__icon"></span> <span class="pulse-button__text">Закажите звонок</span> <span class="pulse-button__rings"></span> <span class="pulse-button__rings"></span> <span class="pulse-button__rings"></span> </button>
Как видите, действительно ничего сложного. Обычная кнопка с несколькими тегами "span" внутри. Первый отвечает за иконку, второй за вывод текста, а остальные, с классом "rings", за круги, которые и имитируют пульсацию.
Давайте добавим стили и добьёмся такого же внешнего вида как в примере выше. Начнем со стилей самой кнопки.
CSS стили кнопки
.pulse-button { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; width: 80px; height: 80px; border-radius: 40px; padding: 10px; border: none; background: #ff0000; box-shadow: 0 5px 35px rgba(0, 0, 0, 0.2); position: fixed; bottom: 50px; right: 50px; cursor: pointer; outline: none; z-index: 1000; }
Туи все стандартно. При помощи flexbox выровнял все по центру. Задал размеры, форму, цвет, позиционирования и положение.
Новичкам:
Управлять положением кнопки можно при помощи атрибутов "left", "right", "top", "bottom". У меня кнопка располагается справа внизу на расстоянии 50 пикселей. Я использую "bottom: 50px;" и "right: 50px;". Если вам нужно справа вверху, то удалите мои атрибуты и впишите, например, "top: 100px;" и "left: 100px".
Кроме, возможна ситуация, когда кнопку при скролле будут перекрывать другие элементы сайта. Для этого нужно узнать у этого элемента значение z-index и сделать у кнопки его выше. Аналогично и модальным окном. Может случиться так, что оно не будет перекрывать кнопку. В таком случае нужно сделать у модального окна значения атрибута z-index повыше.
Подробнее про z-index можно почитать на MDN.
Теперь давайте стилизуем "span" с иконкой и текстом, а также добьёмся того, чтобы при наведении они меняли друг друга.
Начнем с иконки, так как у нас она видна по умолчанию.
.pulse-button__icon { display: block; width: 30px; height: 30px; background: url("../img/phone.svg") center center/cover no-repeat; transition: .3s; }
Надеюсь, тут сложностей не возникло. Единственное, если картинка не отображается, то почитайте про абсолютные и относительные пути и поправьте путь к картинке относительно структуры вашего сайта.
Теперь займемся блоком с текстом.
.pulse-button__text { display: block; width: 100%; height: 30px; font: 12px 'Open Sans', sans-serif; color: #fff; text-align: center; line-height: 1.2; opacity: 0; visibility: hidden; position: absolute; transition: .3s; margin-top: 1px; }
Тут тоже без сюрпризов. Временно можете закомментировать блок с иконкой, а у текста инвертировать "opacity" и "hidden", чтобы отцентрировать текст в случае, если используете другой шрифт. Сейчас этот блок невидно, так как логика в том, чтобы показать его только при наведении на кнопку. Давайте сделаем это.
.pulse-button:hover .pulse-button__icon { opacity: 0; visibility: hidden; position: absolute; transition: .3s; } .pulse-button:hover .pulse-button__text { transition: .3s; opacity: 1; visibility: visible; position: relative; }
При наведении на кнопку при помощи "opacity", "visibility" и "position" скрываем область с иконкой и показываем "span" с текстом. "Transition" отвечает за плавность.
Как сделать пульсации на CSS
Теперь займемся стилизацией окружностей, которые отвечают за имитацию пульсации. Как вы помните - у нас их 3.
.pulse-button__rings { border: 1px solid #ff0000; position: absolute; top: 0; left: 0; bottom: 0; right: 0; height: auto; width: auto; border-radius: 50%; animation-duration: 2.0s; animation-name: pulse_1; animation-iteration-count: infinite; z-index: -1; } .pulse-button__rings:nth-child(2) { animation-name: pulse_2; } .pulse-button__rings:nth-child(3) { animation-name: pulse_3; }
Тут самое интересное это анимация. Говорю, что длиться она будет 2 секунды, бесконечно раз. В "annimation-name" передаю название анимации, вид которой описан ниже. "Border" - отвечает за толщину окружности.
@keyframes pulse_1 { from { opacity: 1; transform: scale(0.9, 0.9); } to { opacity: 0; transform: scale(1.3, 1.3); } } @keyframes pulse_2 { from { opacity: 1; transform: scale(0.8, 0.8); } to { opacity: 0; transform: scale(1.5, 1.5); } } @keyframes pulse_3 { from { opacity: 1; transform: scale(0.8, 0.8); } to { opacity: 0; transform: scale(1.7, 1.7); } }
Как видите, анимация достаточно примитивная. Меняется только прозрачность и масштаб, но это и позволяет добиться нужно эффекта.
О том как сделать вызов модального окна при клике на любую кнопку подробно описано в статье: "Как сделать модальное окно на сайте". Там разбираемся в 2 способах. Первый описывает как это сделать на чистом js, а второй - при помощи jQuery.
А на сегодня - все. Если возникнут вопросы - смело задавайте их в комментариях.
Исходник пульсирующей кнопки
Размер: 0,004 мб
8 комментариев
Спасибо!
Иконку телефона только не видно - не пойму в чем причина....
вроде разобрался
Алексей, отлично. В путях, обычно, причина.
Ekaterina, вот, например:
Как по мне, так устарел лет 5 назад.
Вот бы ещё при наведении выпадала менюшка с иконками: обратный звонок и позвонить... в идеале ещё месенджеры...
Алексей, это уже целый виджет получится. А в чем сложность возникла при реализации? Есть еще несколько кнопок, которые скрыты и расположены там же, где основная, при наведении меняем (инвертируем) у них прозрачность и visibility и меняем положение на чуть повыше или левее/правее.
Дмитрий Давыдов , подумаю... )) Спасибо!