Popper.js — это библиотека для управления позиционированием элементов на веб-странице. Основная цель — обеспечивать динамическое позиционирование всплывающих элементов, таких как тултипы, выпадающие меню, поповеры и модальные окна, относительно целевого элемента (reference element). Основные понятия:
top, bottom, left,
right и их вариации с -start и
-end.Popper создается через функцию
createPopper(reference, popper, options):
import { createPopper } from '@popperjs/core';
const reference = document.querySelector('#button');
const popper = document.querySelector('#tooltip');
createPopper(reference, popper, {
placement: 'bottom',
modifiers: [
{
name: 'offset',
options: {
offset: [0, 8], // смещение по оси X и Y
},
},
],
});
placement определяет начальное направление Popper
относительно reference.modifiers позволяет детально управлять
поведением: смещение, адаптация к границам, скрытие при отсутствии
видимости reference.Модификаторы — это ключевой инструмент Popper.js. Они применяются последовательно и могут менять положение, стиль и стратегию Popper. Основные встроенные модификаторы:
position, transform и top/left
Popper.Пример использования нескольких модификаторов:
createPopper(reference, popper, {
placement: 'top',
modifiers: [
{ name: 'offset', options: { offset: [0, 10] } },
{ name: 'flip', options: { fallbackPlacements: ['right', 'left'] } },
{ name: 'preventOverflow', options: { padding: 5 } },
],
});
Popper.js поддерживает две стратегии позиционирования:
Установка стратегии через модификатор computeStyles:
modifiers: [
{
name: 'computeStyles',
options: {
strategy: 'fixed',
},
},
]
Чтобы стрелка Popper корректно позиционировалась, необходимо указать
элемент стрелки и включить модификатор arrow:
const arrow = document.querySelector('#arrow');
createPopper(reference, popper, {
placement: 'bottom',
modifiers: [
{
name: 'arrow',
options: { element: arrow, padding: 5 },
},
],
});
element — DOM-элемент стрелки.padding — расстояние от границ Popper.Popper.js позволяет обновлять положение Popper в реальном времени, когда меняется размер или положение reference:
const instance = createPopper(reference, popper);
instance.update(); // вручную пересчитывает позицию
Для постоянного обновления можно использовать наблюдатель
ResizeObserver или события скролла/изменения размера
окна.
После использования Popper важно корректно уничтожать экземпляр, чтобы не было утечек памяти:
const instance = createPopper(reference, popper);
// по завершении работы
instance.destroy();
Custom modifiers позволяют создавать уникальное поведение Popper:
const customModifier = {
name: 'logPosition',
enabled: true,
phase: 'afterWrite',
fn({ state }) {
console.log(`Popper position: ${state.styles.popper.top}, ${state.styles.popper.left}`);
},
};
createPopper(reference, popper, {
modifiers: [customModifier],
});
phase — стадия жизненного цикла Popper
(read, main, write).fn — функция, которая получает состояние и может
изменять позиционирование.Popper.js широко используется с React, Vue и Angular. В React
существуют обертки вроде @popperjs/react, которые упрощают
создание компонента Popper через хук:
import { usePopper } from 'react-popper';
const [referenceElement, setReferenceElement] = useState(null);
const [popperElement, setPopperElement] = useState(null);
const { styles, attributes } = usePopper(referenceElement, popperElement, {
placement: 'right',
});
return (
<>
<button ref={setReferenceElement}>Click me</button>
<div ref={setPopperElement} style={styles.popper} {...attributes.popper}>
Tooltip content
</div>
</>
);
update() и наблюдатели.flip и preventOverflow для
адаптивного позиционирования.Popper корректно вычисляет позиции даже при масштабировании или прокрутке, если включены:
boundary — контейнер, относительно которого проверяется
overflow.tether — при включении удерживает Popper в пределах
boundary даже при flip.modifiers: [
{
name: 'preventOverflow',
options: { boundary: document.body, tether: true },
},
]
Для визуальных регрессионных тестов важно, чтобы Popper корректно рендерился в статическом состоянии:
Это обеспечивает стабильность интерфейса и предотвращает ложные срабатывания тестов при изменении контента или размера окна.