Кастомные placement конфигурации

Popper.js предоставляет мощный механизм для управления позиционированием всплывающих элементов, таких как тултипы, выпадающие меню и модальные подсказки. Одним из ключевых элементов управления является параметр placement, который определяет, где именно относительно целевого элемента будет отображаться поппер. Помимо стандартных значений (top, bottom, left, right и их вариаций с -start и -end), Popper.js позволяет создавать кастомные конфигурации placement для точного контроля позиции.


Основы параметра placement

placement принимает строку, описывающую направление и выравнивание:

  • Направления: top, bottom, left, right — определяют основное расположение.
  • Выравнивание: -start, -end — уточняют горизонтальное или вертикальное смещение относительно цели.

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

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

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

createPopper(button, tooltip, {
  placement: 'top-start'
});

В этом примере тултип будет располагаться сверху кнопки, начиная с её левой стороны.


Кастомные placement через модификатор offset

Для создания уникальных смещений можно использовать модификатор offset. Он позволяет управлять расстоянием между поппером и reference-элементом, а также сдвигать его по оси X или Y.

createPopper(button, tooltip, {
  placement: 'top',
  modifiers: [
    {
      name: 'offset',
      options: {
        offset: [10, 20] // [skew по основной оси, смещение по поперечной оси]
      }
    }
  ]
});
  • Первый параметр массива задаёт смещение вдоль основной оси (top → вертикальная ось, left → горизонтальная ось).
  • Второй параметр задаёт смещение вдоль перпендикулярной оси.

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


Полностью кастомные placement с модификатором popperOffsets

Для более точного контроля используется модификатор popperOffsets. Он позволяет задать координаты поппера вручную:

createPopper(button, tooltip, {
  modifiers: [
    {
      name: 'popperOffsets',
      enabled: true,
      phase: 'main',
      fn({ state }) {
        state.styles.popper.top = '50px';
        state.styles.popper.left = '200px';
      }
    }
  ]
});

Особенности:

  • Дает полный контроль над позиционированием.
  • Работает независимо от placement.
  • Позволяет динамически изменять координаты на основе любых условий.

Использование кастомных placement через computeStyles

Модификатор computeStyles отвечает за вычисление финальных координат с учетом смещений и ограничений. При создании кастомного placement его можно настраивать:

createPopper(button, tooltip, {
  modifiers: [
    {
      name: 'computeStyles',
      options: {
        adaptive: false, // отключает автоматическую адаптацию к краям окна
        gpuAcceleration: false // можно использовать топ/лев координаты напрямую
      }
    }
  ]
});

adaptive: false особенно полезен, когда требуется, чтобы поппер не менял позицию при скролле или изменении размера окна, что важно для кастомных layouts.


Динамическая смена placement

Popper.js поддерживает динамическую смену placement в зависимости от доступного пространства или других условий. Для этого используется модификатор flip:

createPopper(button, tooltip, {
  placement: 'bottom',
  modifiers: [
    {
      name: 'flip',
      options: {
        fallbackPlacements: ['top-start', 'right', 'left'], // возможные альтернативы
        padding: 8
      }
    }
  ]
});

flip автоматически выбирает наилучший placement из заданных fallback в случае, если основной placement перекрывается границами viewport. Для кастомных решений можно комбинировать flip с offset, чтобы добиться уникальных позиций.


Кастомные функции для placement

Начиная с версии Popper.js 2, можно создавать полностью кастомные функции для определения placement:

createPopper(button, tooltip, {
  placement: ({ reference, popper, placement }) => {
    if (window.innerWidth < 600) return 'bottom';
    return 'top-end';
  }
});

Особенности такого подхода:

  • Функция принимает объект с текущими элементами и их размерами.
  • Позволяет возвращать строку с нужным placement.
  • Дает гибкость для адаптивных интерфейсов.

Комбинирование кастомных методов

Для сложных сценариев рекомендуется комбинировать:

  1. Функции для динамического выбора placement — выбор базового направления.
  2. offset — для смещения относительно reference-элемента.
  3. popperOffsets — для точного позиционирования по координатам.
  4. computeStyles с адаптацией — контроль за поведением при скролле или изменении размеров.
  5. flip — обеспечение корректного отображения на экранах разной ширины.

Такой подход позволяет создавать абсолютно любые, кастомные позиции попперов без ограничения стандартными предустановленными вариантами.