Coordinates и positioning

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

Координаты и прямоугольники

Popper.js оперирует bounding rects элементов — объектами с координатами top, right, bottom, left, width и height. Эти данные позволяют вычислять точное положение popper относительно reference и viewport. В библиотеке различают несколько систем координат:

  • Client coordinates (clientX, clientY) — координаты относительно видимой области окна браузера. Используются при позиционировании относительно скроллинга viewport.
  • Page coordinates (pageX, pageY) — координаты относительно всей страницы, учитывают вертикальный и горизонтальный скролл.
  • Offset coordinates — сдвиг popper относительно reference с использованием свойств offset или модификатора offset.

Вычисление позиции Popper

Popper.js использует алгоритм, основанный на вычислении прямоугольников и применении модификаторов. Основные шаги:

  1. Получение размеров и координат reference и popper

    const referenceRect = reference.getBoundingClientRect();
    const popperRect = popper.getBoundingClientRect();
  2. Вычисление основной позицииtop, bottom, left, right в зависимости от выбранного placement (top, bottom, left, right, auto).

    Для placement: 'top' координаты вычисляются как:

    const top = referenceRect.top - popperRect.height;
    const left = referenceRect.left + (referenceRect.width - popperRect.width) / 2;
  3. Применение модификаторов — такие как offset, flip, preventOverflow, которые корректируют рассчитанные координаты.

Модификатор offset

Модификатор offset позволяет задать смещение popper относительно reference. Синтаксис:

const popperInstance = Popper.createPopper(reference, popper, {
  modifiers: [
    {
      name: 'offset',
      options: {
        offset: [0, 10] // [сколько по горизонтали, сколько по вертикали]
      },
    },
  ],
});

Значение [0, 10] означает отсутствие горизонтального смещения и вертикальное смещение на 10 пикселей в сторону, указанную placement.

Placement и ориентация

Placement определяет основную ориентацию popper относительно reference:

  • top, bottom, left, right — прямое позиционирование.
  • top-start, top-end и аналогично для других направлений — смещение к началу или концу reference.
  • auto — Popper.js сам выбирает оптимальное направление на основе доступного пространства.

При использовании auto библиотека проверяет границы viewport и избегает перекрытия окна браузера.

PreventOverflow и ограничения

Модификатор preventOverflow предотвращает выход popper за пределы контейнера или viewport. Основные параметры:

  • boundary — элемент или массив элементов, относительно которых запрещён выход.
  • padding — внутренний отступ от границ, чтобы popper не прилипал к краям.

Пример использования:

const popperInstance = Popper.createPopper(reference, popper, {
  modifiers: [
    {
      name: 'preventOverflow',
      options: {
        boundary: document.body,
        padding: 8,
      },
    },
  ],
});

Flip и динамическая ориентация

Модификатор flip позволяет автоматически изменять placement, если основной вариант не помещается на экране. Он работает в связке с preventOverflow:

const popperInstance = Popper.createPopper(reference, popper, {
  modifiers: [
    { name: 'flip', options: { fallbackPlacements: ['top', 'right', 'left'] } },
  ],
});

Библиотека проверяет доступное пространство и выбирает первый подходящий вариант из массива fallbackPlacements.

Работа с позиционированием через virtual elements

Popper.js поддерживает virtual elements, которые не являются реальными DOM-элементами. Это полезно для позиционирования относительно координат курсора или canvas. Структура virtual element:

const virtualElement = {
  getBoundingClientRect: () => ({
    width: 0,
    height: 0,
    top: 100,
    bottom: 100,
    left: 150,
    right: 150,
  }),
};

Создание Popper для virtual element аналогично обычному:

const popperInstance = Popper.createPopper(virtualElement, popper);

TransformOrigin и GPU acceleration

Для повышения производительности Popper.js применяет CSS-свойство transform: translate3d(x, y, 0) вместо изменения top/left. Это позволяет использовать аппаратное ускорение GPU и предотвращает перерисовку макета страницы.

  • transformOrigin изменяется автоматически на основе placement, чтобы анимации и всплытия выглядели естественно.
  • Пример: для placement top transformOrigin устанавливается в bottom center, для leftcenter right.

Взаимодействие с scroll и resize

Popper.js отслеживает события скролла и изменения размеров viewport. При изменении позиции reference popper автоматически пересчитывает координаты. Для этого используется встроенный eventListeners модификатор:

const popperInstance = Popper.createPopper(reference, popper, {
  modifiers: [
    { name: 'eventListeners', options: { scroll: true, resize: true } },
  ],
});

Это гарантирует корректное позиционирование при динамическом изменении страницы или прокрутке.


Popper.js реализует позиционирование через точные вычисления координат, модификаторы и оптимизацию с GPU. Управление placement, offset, overflow и flip позволяет строить сложные и адаптивные интерфейсы с динамическими всплывающими элементами, полностью интегрированными с DOM и viewport.