В Popper.js термин root boundary обозначает
элемент, который ограничивает область, в которой всплывающий элемент
(popper) может отображаться. Этот параметр напрямую влияет на
вычисление позиции, предотвращение выхода за границы и срабатывание
модификаторов, таких как preventOverflow.
По умолчанию Popper.js использует viewport как границу. Однако при работе с прокручиваемыми контейнерами или сложной структурой DOM часто требуется задать собственную границу.
Root boundary задаётся через опцию boundary внутри
конфигурации Popper:
import { createPopper } from '@popperjs/core';
const reference = document.querySelector('#button');
const popper = document.querySelector('#tooltip');
createPopper(reference, popper, {
modifiers: [
{
name: 'preventOverflow',
options: {
boundary: document.querySelector('#container') // root boundary
},
},
],
});
Ключевые моменты:
boundary может принимать:
HTMLElement) – граница будет ограничена
этим элементом.clippingParents – Popper.js будет использовать
ближайшие родительские элементы с обрезкой
(overflow: hidden, scroll, auto)
в качестве границ.viewport – стандартная граница, окно браузера.document – вся страница.root boundary определяет не только визуальные
границы, но и влияет на логику модификаторов, таких как
flip, hide и
preventOverflow.
Модификатор preventOverflow предотвращает выход
всплывающего элемента за границы. Использование кастомного root
boundary позволяет контролировать, где Popper может
перемещаться:
modifiers: [
{
name: 'preventOverflow',
options: {
boundary: document.querySelector('#scrollable-container'),
padding: 8
},
},
]
Пояснения:
padding – добавляет внутреннее расстояние между Popper
и границей.flip).modifiers: [
{
name: 'flip',
options: {
fallbackPlacements: ['top', 'bottom'],
boundary: document.querySelector('#container') // root boundary
},
},
]
Popper сначала проверяет root boundary, затем fallback placements, чтобы найти наилучшую видимую позицию.
Для элементов внутри скроллящихся контейнеров важно корректно задавать root boundary. В противном случае Popper может визуально «выпадать» за пределы видимой области контейнера.
const scrollContainer = document.querySelector('#scrollable-area');
createPopper(reference, popper, {
modifiers: [
{
name: 'preventOverflow',
options: {
boundary: scrollContainer,
tether: true // позволяет Popper оставаться «прицепленным» к reference
},
},
],
});
Особенности:
tether: true закрепляет Popper относительно reference
даже при прокрутке.transform, Popper корректно рассчитывает координаты внутри
transformed space.position: fixed root boundary всё
равно учитывается, но координаты рассчитываются относительно viewport, а
не обычного потока документа.clippingParents, если структура DOM
сложная и неизвестно заранее, какой элемент будет ограничивать
Popper.padding для обеспечения визуального
пространства между Popper и границей.overflow,
transform) на расчёт позиции.preventOverflow.Root boundary — ключевой инструмент Popper.js для управления видимостью и положением всплывающих элементов. Правильное определение root boundary обеспечивает стабильное поведение Popper в сложных и прокручиваемых интерфейсах, предотвращает визуальные артефакты и улучшает UX.