Обработка overflow

Popper.js предоставляет мощный механизм управления положением всплывающих элементов (popper) относительно целевых элементов (reference). Одним из ключевых аспектов позиционирования является корректная работа с overflow, когда поппер выходит за границы видимой области или контейнера. Для решения этой задачи Popper.js использует систему модификаторов, которая позволяет гибко управлять поведением всплывающих элементов при ограниченных пространствах.


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

Модификатор preventOverflow отвечает за предотвращение выхода поппера за пределы заданной области. Он проверяет размеры и позицию popper относительно boundary (границы контейнера, viewport или любого другого элемента) и корректирует положение, чтобы элемент оставался видимым.

Ключевые параметры:

  • mainAxis — управление основной осью (по горизонтали или вертикали, в зависимости от placement). Если установлено в true, модификатор будет корректировать положение по этой оси.

  • altAxis — управление второстепенной осью. Позволяет предотвращать overflow и по перпендикулярной оси.

  • boundary — задает границу, относительно которой производится проверка. Может быть:

    • viewport — окно браузера,
    • scrollParent — ближайший прокручиваемый контейнер,
    • любой DOM-элемент.
  • tether — булево значение, которое позволяет попперу “приклеиваться” к границе при ограниченном пространстве. Если false, элемент может выходить за границу.

  • padding — внутренний отступ от границы, чтобы popper не прилипал вплотную.

Пример настройки:

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

const popperInstance = createPopper(referenceElement, popperElement, {
  modifiers: [
    {
      name: 'preventOverflow',
      options: {
        boundary: 'viewport',
        padding: 8,
        mainAxis: true,
        altAxis: true,
      },
    },
  ],
});

В этом примере popper не выйдет за пределы окна браузера и сохранит отступ в 8 пикселей.


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

Даже при использовании preventOverflow может возникнуть ситуация, когда на основной оси элемент не помещается. В таких случаях применяется модификатор flip, который позволяет автоматически изменять placement.

Особенности работы:

  • Определяет список допустимых позиций для popper, например ['top', 'right', 'bottom', 'left'].
  • Проверяет доступное пространство и выбирает позицию, где popper полностью помещается.
  • Может работать в комбинации с preventOverflow для предотвращения выхода за границы.

Параметры flip:

  • fallbackPlacements — массив альтернативных позиций.
  • boundary — граница, аналогично preventOverflow.
  • padding — внутренний отступ.

Пример:

modifiers: [
  {
    name: 'flip',
    options: {
      fallbackPlacements: ['top', 'right', 'bottom', 'left'],
      boundary: 'viewport',
      padding: 5,
    },
  },
]

Если popper не помещается снизу, модификатор попробует разместить его сверху, затем справа и слева.


Совмещение preventOverflow и flip

Эти два модификатора часто используются вместе для гибкого управления overflow:

  1. flip подбирает подходящее расположение.
  2. preventOverflow корректирует позицию, чтобы поппер не выходил за границы.

Пример интеграции:

const popperInstance = createPopper(referenceElement, popperElement, {
  placement: 'bottom',
  modifiers: [
    {
      name: 'flip',
      options: {
        fallbackPlacements: ['top', 'right', 'left'],
      },
    },
    {
      name: 'preventOverflow',
      options: {
        boundary: 'viewport',
        padding: 10,
      },
    },
  ],
});

Настройка границ (boundary) и отступов (padding)

preventOverflow позволяет указать любую DOM-границу. Это особенно полезно при работе с scrollable контейнерами или сложными макетами.

Возможные значения boundary:

  • 'viewport' — область видимого окна.
  • 'document' — вся страница.
  • DOM-элемент — любой элемент с ограниченной областью видимости.
  • 'clippingParents' — ближайшие элементы-клипперы (по умолчанию).

Пример:

{
  name: 'preventOverflow',
  options: {
    boundary: document.querySelector('.modal-container'),
    padding: 12,
  },
}

Popper будет оставаться внутри .modal-container и не будет прилипать к границам благодаря отступу в 12 пикселей.


Влияние модификаторов на производительность

  • Чем больше модификаторов и вычислений, тем выше нагрузка на рендеринг.
  • Рекомендуется использовать mainAxis и altAxis выборочно, чтобы минимизировать лишние пересчеты.
  • Если popper статичен и не требует динамической подстройки при скролле или resize, можно отключить лишние модификаторы для оптимизации.

Дополнительные методы контроля overflow

  1. tether и tetherOffset Позволяют настроить минимальное расстояние от границы, чтобы popper оставался видимым, но при этом не “прыгал” слишком резко при ограниченном пространстве.

  2. flipVariations Управляет вариациями размещения при ограниченном пространстве, например top-start, top-end и т.д.

  3. События обновления (update) Для динамических элементов важно вызвать popperInstance.update() после изменения размеров контейнера или содержимого.


Практические советы

  • Для всплывающих подсказок (tooltip) лучше использовать комбинацию flip + preventOverflow.
  • Для больших панелей (dropdown, popover) иногда достаточно только preventOverflow с корректными границами.
  • В сложных макетах с прокручиваемыми контейнерами всегда проверять, что boundary правильно настроен.

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