Понятие позиционирования элементов

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

Контейнеры и элементы

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

Popper.js всегда рассчитывает позицию относительно reference, автоматически подбирая координаты top, bottom, left, right с учётом размеров и ограничений видимой области.

Основные концепции позиционирования

1. Placement

placement задаёт базовое расположение Popper относительно reference. Основные значения:

  • top — сверху
  • bottom — снизу
  • left — слева
  • right — справа

Дополнительные уточнения через -start и -end:

  • top-start — сверху, по левому краю
  • bottom-end — снизу, по правому краю

Popper.js также позволяет динамически менять placement, если выбранная позиция не помещается на экране.

2. Modifiers

Модификаторы (modifiers) — это функции, которые изменяют поведение Popper на этапе расчёта позиции. Основные модификаторы:

  • offset — задаёт смещение Popper относительно reference по оси X и Y.

    modifiers: [{ name: 'offset', options: { offset: [0, 8] } }]
  • flip — автоматически переворачивает Popper на противоположную сторону, если место ограничено.

  • preventOverflow — предотвращает выход Popper за границы видимой области.

  • arrow — позиционирует стрелку, указывающую на reference.

Модификаторы можно комбинировать, управляя порядком их выполнения через phase (например, main, write, beforeRead).

3. Смещение и точка привязки

Popper.js использует точку привязки (reference point), определяемую размерами reference. Расчёт координат Popper выполняется с учётом:

  • ширины и высоты reference
  • ширины и высоты Popper
  • смещений, заданных через modifiers

Функция смещения может быть кастомной:

modifiers: [{
  name: 'offset',
  options: {
    offset: ({ placement, reference, popper }) => {
      if (placement.startsWith('top')) return [0, -10];
      return [0, 10];
    }
  }
}]

4. Динамическое позиционирование

Popper.js пересчитывает позицию при изменении размера окна или скролле контейнера. Для этого используется autoUpdate, которая слушает события и корректирует координаты Popper в реальном времени.

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

const popperInstance = createPopper(reference, popper, {
  placement: 'bottom',
  modifiers: [{ name: 'offset', options: { offset: [0, 10] } }]
});

autoUpdate(reference, popper, popperInstance.update);

5. Работа со стрелками (arrow)

Стрелка — это элемент Popper, визуально указывающий на reference. Для её корректного позиционирования необходимо:

  • добавить элемент стрелки внутри Popper
  • определить модификатор arrow, передав в него селектор или DOM-элемент стрелки
  • Popper автоматически вычислит позицию стрелки, учитывая смещение и размеры Popper
modifiers: [
  { name: 'arrow', options: { element: '.arrow' } },
  { name: 'offset', options: { offset: [0, 8] } }
]

6. Boundary и rootBoundary

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

  • boundary — контейнер, ограничивающий Popper (например, элемент с overflow: hidden)
  • rootBoundary — окно браузера (viewport) по умолчанию

Модификатор preventOverflow использует эти параметры для ограничения позиции Popper.

7. Сценарии использования

  • Тултипы: небольшие подсказки, выскакивающие при наведении
  • Дропдауны: списки с опциями, выстраивающиеся под кнопкой
  • Модальные подсказки: уведомления или подсказки с динамическим размещением
  • Контекстные меню: всплывают рядом с элементом, на который нажали

Popper.js идеально справляется с адаптивной версткой, когда элементы могут менять размер или положение в зависимости от экрана.

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

  • Всегда указывать placement, чтобы Popper имел базовую ориентацию
  • Использовать flip и preventOverflow для адаптивности
  • При работе со стрелками соблюдать размер стрелки и отступы от reference
  • Для сложных смещений применять функцию offset с учётом конкретной логики интерфейса

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