Popovers

Popper.js — это мощная библиотека для управления позиционированием элементов поверх других элементов в браузере. Она особенно полезна для реализации popovers, всплывающих подсказок и меню, которые должны динамически подстраиваться под размер окна и положение целевого элемента.

Создание Popover

Для начала необходимо определить элемент-опорный элемент (reference element) и popover. Reference element — это элемент, относительно которого будет позиционироваться popover. Popover может быть любым HTML-элементом, скрытым по умолчанию.

const referenceElement = document.querySelector('#button');
const popoverElement = document.querySelector('#popover');

const popperInstance = Popper.createPopper(referenceElement, popoverElement, {
  placement: 'bottom', // расположение popover относительно referenceElement
});

Ключевой параметр placement задаёт позицию:

  • top, bottom, left, right
  • Дополнительно можно использовать -start и -end для выравнивания по краю, например: bottom-start.

Настройка смещения

Часто требуется небольшое смещение popover от reference element. Для этого используется модификатор offset:

const popperInstance = Popper.createPopper(referenceElement, popoverElement, {
  placement: 'bottom',
  modifiers: [
    {
      name: 'offset',
      options: {
        offset: [0, 8], // смещение по оси X и Y
      },
    },
  ],
});

offset: [0, 8] означает, что popover будет смещён на 8 пикселей вниз относительно стандартной позиции.

Автоматическое смещение при переполнении

Чтобы popover не выходил за границы окна или контейнера, используется модификатор preventOverflow:

modifiers: [
  {
    name: 'preventOverflow',
    options: {
      boundary: 'viewport', // можно указать конкретный контейнер
    },
  },
]

Для автоматического изменения позиции при нехватке места применяют модификатор flip:

modifiers: [
  {
    name: 'flip',
    options: {
      fallbackPlacements: ['top', 'right', 'left'], 
    },
  },
]

Если выбранная позиция (bottom) не помещается, popover автоматически перелистывается на top, right или left.

Динамическое обновление popover

Popper.js позволяет динамически обновлять положение popover при изменении размеров окна или содержимого:

popperInstance.update();

Для автоматического слежения за изменениями DOM или прокруткой можно использовать eventListeners модификатор:

modifiers: [
  {
    name: 'eventListeners',
    options: {
      scroll: true,
      resize: true,
    },
  },
]

Управление видимостью

Popovers часто скрываются по умолчанию. Для управления видимостью используют CSS и Jav * aScript:

button.addEventListener('click', () => {
  popoverElement.classList.toggle('show');
  popperInstance.update(); // обязательно обновить позицию при показе
});

CSS может содержать:

#popover {
  display: none;
  position: absolute;
  z-index: 9999;
}

#popover.show {
  display: block;
}

Применение модификаторов для кастомизации

Popper.js имеет гибкую систему модификаторов, позволяющую:

  • добавлять тени и анимацию
  • изменять размеры popover
  • обрезать контент, чтобы он не выходил за контейнер

Пример кастомного модификатора для ограничения ширины:

modifiers: [
  {
    name: 'sameWidth',
    enabled: true,
    phase: 'beforeWrite',
    fn({ state }) {
      state.styles.popper.width = `${state.rects.reference.width}px`;
    },
  },
]

Popover теперь будет точно соответствовать ширине reference element.

Интеграция с интерактивными элементами

Popovers часто содержат кнопки, формы или другие интерактивные элементы. Чтобы обеспечить корректное позиционирование при взаимодействии пользователя, необходимо:

  • включать eventListeners модификатор
  • обновлять popover при изменении размера интерактивного контента
const form = popoverElement.querySelector('form');
form.addEventListener('input', () => {
  popperInstance.update();
});

Рекомендации по производительности

  • Создавать popperInstance только при необходимости (например, при первом показе popover).
  • Отключать eventListeners для скрытых popovers.
  • Минимизировать количество одновременно активных popperInstance на странице.

Popper.js обеспечивает точное и гибкое позиционирование popovers, позволяя создавать сложные интерактивные интерфейсы с адаптивной версткой, предотвращая перекрытие и переполнение. Правильное использование модификаторов offset, flip, preventOverflow и кастомных функций позволяет полностью контролировать поведение всплывающих элементов.