Как сделать пульсирующую кнопку

Привет, друзья. В прошлой статье обещал рассказать о том, как сделать пульсирующую кнопку в углу экрана, аналогичную тем, которые вы могли видеть у разных виджетов обратного звонка. Меня несколько раз просили рассказать как это сделать и уже на 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 мб

Похожие публикации

10 комментариев

  1. Алексей

    Спасибо!

  2. Алексей

    Иконку телефона только не видно - не пойму в чем причина....

    1. Алексей

      вроде разобрался

    2. Дмитрий Давыдов

      Алексей, отлично. В путях, обычно, причина.

    3. Дмитрий Давыдов

      Ekaterina, вот, например:

      Как по мне, так устарел лет 5 назад.

    4. Сергей

      Алексей, не подскажите как разобрались? такая же проблема

  3. Алексей

    Вот бы ещё при наведении выпадала менюшка с иконками: обратный звонок и позвонить... в идеале ещё месенджеры...

    1. Дмитрий Давыдов

      Алексей, это уже целый виджет получится. А в чем сложность возникла при реализации? Есть еще несколько кнопок, которые скрыты и расположены там же, где основная, при наведении меняем (инвертируем) у них прозрачность и visibility и меняем положение на чуть повыше или левее/правее.

    2. Alex

      Алексей,
      Это можно сделать при помощи engagebox
      __https://www.tassos.gr/joomla-extensions/engagebox
      В нем настраивается логика, при нажатии на пульсирующую кнопку - показать иконки(при этом скрыть саму пульсирующую кнопку) и вторая логика, при скрытии кнопок, опять показать пульсирующую кнопку.

  4. Алексей

    Дмитрий Давыдов , подумаю... )) Спасибо!

Добавить комментарий