Что такое Popper.js и зачем он нужен

Popper.js — это библиотека JavaScript, предназначенная для управления позиционированием всплывающих элементов на веб-странице, таких как подсказки (tooltips), всплывающие меню (dropdowns), модальные окна и другие плавающие элементы. Основная задача Popper.js — гарантировать, что элемент всегда корректно располагается относительно своего «родителя» или целевого элемента, учитывая размеры окна, скролл и другие динамические изменения на странице.

Popper.js работает на принципе «reference element — popper element»:

  • Reference element — это элемент, относительно которого позиционируется всплывающий блок.
  • Popper element — это сам всплывающий блок, который должен «следовать» за reference element.

Установка и подключение

Библиотека доступна через npm и CDN.

Через npm:

npm install @popperjs/core

Через CDN:

<script src="https://unpkg.com/@popperjs/core@2"></script>

После подключения можно создавать попперы с помощью функции createPopper.

Создание базового поппера

Базовое создание поппера выглядит следующим образом:

import { createPopper } from '@popperjs/core';

const reference = document.querySelector('#button');
const popper = document.querySelector('#tooltip');

createPopper(reference, popper, {
  placement: 'top',
});
  • placement определяет позицию поппера относительно reference element. Возможные значения: 'top', 'bottom', 'left', 'right', а также вариации с -start и -end для выравнивания по краям.

Опции и конфигурация

Popper.js предоставляет широкий набор опций для точного контроля:

1. placement

Определяет начальное расположение поппера. Например:

placement: 'bottom-end'

обозначает, что поппер будет размещён под элементом и выровнен по его правому краю.

2. modifiers

Модификаторы — это плагины, которые изменяют поведение поппера. Основные модификаторы:

  • offset — задаёт смещение поппера относительно reference element:
modifiers: [{
  name: 'offset',
  options: {
    offset: [0, 10], // смещение по горизонтали и вертикали
  },
}]
  • flip — автоматически изменяет позицию поппера, если выбранное место не помещается на экране:
modifiers: [{ name: 'flip', options: { fallbackPlacements: ['top', 'right'] } }]
  • preventOverflow — предотвращает выход поппера за пределы окна:
modifiers: [{ name: 'preventOverflow', options: { padding: 8 } }]
  • arrow — добавляет стрелку, указывающую на reference element:
modifiers: [{
  name: 'arrow',
  options: { element: document.querySelector('#arrow') },
}]

3. strategy

Определяет метод позиционирования: 'absolute' (по умолчанию) или 'fixed' (позволяет попперу оставаться на месте при скролле контейнера).

Динамическое обновление позиции

Popper.js автоматически обновляет позицию при изменении размеров окна или scroll. Для ручного обновления используется метод:

popperInstance.update();

Для уничтожения поппера и освобождения ресурсов:

popperInstance.destroy();

Примеры сложных сценариев

Адаптивный поппер с переключением позиций

createPopper(reference, popper, {
  placement: 'bottom',
  modifiers: [
    { name: 'flip', options: { fallbackPlacements: ['top', 'right', 'left'] } },
    { name: 'preventOverflow', options: { padding: 5 } },
  ],
});

Поппер будет автоматически менять позицию при нехватке места снизу.

Поппер с кастомным смещением и стрелкой

createPopper(reference, popper, {
  placement: 'top',
  modifiers: [
    { name: 'offset', options: { offset: [0, 15] } },
    { name: 'arrow', options: { element: document.querySelector('#arrow') } },
  ],
});

Смещение увеличивает расстояние от reference element, а стрелка остаётся корректно направленной.

Интеграция с фреймворками

Popper.js легко интегрируется с React, Vue и Angular. В React существует обёртка react-popper, которая обеспечивает декларативное создание попперов через компоненты, сохраняя совместимость с жизненным циклом React.

import { usePopper } from 'react-popper';

const [referenceElement, setReferenceElement] = useState(null);
const [popperElement, setPopperElement] = useState(null);
const { styles, attributes } = usePopper(referenceElement, popperElement, { placement: 'bottom' });

<button ref={setReferenceElement}>Hover me</button>
<div ref={setPopperElement} style={styles.popper} {...attributes.popper}>
  Tooltip
</div>

Ключевые преимущества Popper.js

  • Автоматическое позиционирование и поддержка адаптивного расположения.
  • Полная поддержка модификаторов для гибкой настройки поведения.
  • Простая интеграция с современными фреймворками.
  • Лёгкий и производительный, не требует больших зависимостей.

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