Одной из ключевых задач библиотеки Popper.js является корректное позиционирование всплывающих элементов (tooltip, dropdown, popover) относительно опорного элемента (reference), при этом не допуская выхода за пределы видимой области. В реальных интерфейсах это особенно важно: элементы могут обрезаться, становиться недоступными или перекрывать важный контент.
Для решения этой задачи Popper.js использует систему
модификаторов (modifiers), среди которых центральную
роль играет preventOverflow.
Модификатор preventOverflow отвечает за удержание
всплывающего элемента внутри заданных границ.
createPopper(referenceElement, popperElement, {
modifiers: [
{
name: 'preventOverflow',
options: {
boundary: 'clippingParents',
},
},
],
});
Определяет границы, внутри которых должен оставаться popper.
Возможные значения:
'clippingParents' — все родительские элементы с
overflow'viewport' — границы окна браузера'document' — весь документПример:
boundary: document.body
Определяет основную границу, используемую при вычислениях.
Варианты:
'viewport' (по умолчанию)'document'rootBoundary: 'document'
Добавляет отступ от границы, чтобы popper не “прилипал” к краю.
padding: 8
Можно задавать разные значения по сторонам:
padding: {
top: 10,
right: 5,
bottom: 10,
left: 5,
}
По умолчанию Popper корректирует позицию только по основной оси (в
зависимости от placement). Параметр altAxis включает
коррекцию по дополнительной оси.
altAxis: true
Это особенно важно для предотвращения наложений в сложных интерфейсах.
Определяет, должен ли popper оставаться “привязанным” к reference-элементу.
tether: true
Если отключить:
tether: false
popper может полностью оторваться от reference, чтобы остаться в пределах границ.
Позволяет задать дополнительное смещение при tether-поведении.
tetherOffset: 10
Или функция:
tetherOffset: ({ popper, reference }) => {
return popper.width / 2;
}
Модификатор flip меняет сторону размещения, если текущая
не помещается.
Пример:
modifiers: [
{
name: 'flip',
options: {
fallbackPlacements: ['top', 'right'],
},
},
{
name: 'preventOverflow',
},
]
Связка flip + preventOverflow обеспечивает:
Используется для задания смещения, которое затем учитывается
preventOverflow.
{
name: 'offset',
options: {
offset: [0, 10],
},
}
Причины:
boundaryoverflow: hiddenРешение:
boundary: 'viewport'
или указание конкретного контейнера.
Причина:
Решение:
padding: 10
Причина:
Решение:
tether: true
Причина:
Решение:
rootBoundary: 'viewport'
createPopper(button, tooltip, {
placement: 'bottom',
modifiers: [
{
name: 'offset',
options: {
offset: [0, 12],
},
},
{
name: 'flip',
options: {
fallbackPlacements: ['top', 'right'],
},
},
{
name: 'preventOverflow',
options: {
boundary: 'viewport',
padding: 8,
altAxis: true,
tether: true,
},
},
],
});
Некоторые CSS-свойства напрямую влияют на работу Popper:
.container {
overflow: hidden;
}
Ограничивает область видимости и влияет на
clippingParents.
Родительские элементы с
position: relative | absolute | fixed участвуют в
вычислениях.
.container {
transform: translateZ(0);
}
Создаёт новый контекст наложения и может изменить поведение позиционирования.
boundary: modalElement
Позволяет удерживать popper внутри модального контейнера.
Необходимо учитывать document внутри iframe:
rootBoundary: 'document'
Можно комбинировать модификаторы или писать собственные:
const customModifier = {
name: 'customPrevent',
enabled: true,
phase: 'main',
fn({ state }) {
// кастомная логика
},
};
flip, offset и
preventOverflow даёт наилучший результат