В Popper.js boundary — это ограничение, которое предотвращает выход всплывающего элемента за пределы заданной области. Часто требуется, чтобы поппер не выходил за видимую часть страницы или контейнер, в котором он расположен. Одним из наиболее распространённых способов задания границ является использование родительских элементов в качестве boundary.
Popper.js управляет положением всплывающих элементов относительно их reference element (элемент-отправитель), автоматически подстраивая их позицию при изменении окна браузера или прокрутке страницы. Для контроля видимости используются модификаторы, один из которых — preventOverflow. Именно через него задаются границы.
boundary — параметр модификатора preventOverflow. Он может принимать:
'viewport' — границы окна браузера,'scrollParent' — ближайший прокручиваемый родительский
элемент,Для установки родителя как boundary необходимо:
import { createPopper } from '@popperjs/core';
const reference = document.querySelector('#button');
const popper = document.querySelector('#tooltip');
createPopper(reference, popper, {
modifiers: [
{
name: 'preventOverflow',
options: {
boundary: reference.parentElement, // родительский элемент reference
padding: 8, // отступ от границы
},
},
],
});
Ключевые моменты:
reference.parentElement — это прямой родитель элемента
reference.padding предотвращает прилипание поппера к
границе.Иногда требуется учитывать несколько родительских элементов:
const boundaries = [
reference.parentElement,
document.querySelector('#main-container')
];
createPopper(reference, popper, {
modifiers: [
{
name: 'preventOverflow',
options: { boundary: boundaries },
},
],
});
Popper будет стараться удерживать элемент внутри всех указанных контейнеров одновременно. Это особенно полезно при вложенных scrollable контейнерах.
При использовании родительских элементов как boundary важно учитывать их CSS:
position: relative | absolute | fixed — влияет на
расчет offset для поппера.overflow: hidden | scroll | auto — ограничивает видимую
область popper.transform на родителях создаёт containing
block, что меняет систему координат для вычисления
позиции.Пример: если родитель имеет transform: translate(0,0),
popper будет вычисляться относительно этого родителя, а не
документа.
Если родительский элемент изменяется динамически (например, через JavaScript добавляется новый контейнер), boundary следует обновлять:
popper.setOptions({
modifiers: [
{
name: 'preventOverflow',
options: { boundary: newParent }
}
]
});
popper.update();
Это позволяет поддерживать корректное позиционирование после изменений DOM.
Popper.js позволяет комбинировать boundary и offset для точной подгонки позиции:
createPopper(reference, popper, {
modifiers: [
{
name: 'preventOverflow',
options: { boundary: reference.parentElement }
},
{
name: 'offset',
options: { offset: [0, 12] } // смещение по оси Y на 12px
}
]
});
Сочетание этих модификаторов позволяет создавать аккуратные тултипы, меню и подсказки, которые не выходят за пределы родительского контейнера.
scrollParent или прямой родитель, чтобы избежать выхода за
пределы контейнера.viewport как boundary, чтобы учитывать видимую область
экрана.overflow и transform, так как они напрямую
влияют на расчёт позиции.Использование родительских элементов как boundary в Popper.js обеспечивает гибкий и безопасный способ контроля видимости всплывающих элементов внутри интерфейса, предотвращая их выход за пределы контейнеров и сохраняя удобство для пользователей.