В библиотеке Floating UI управление переворотом (flip) позволяет
динамически изменять позицию всплывающего элемента относительно его
опоры, чтобы избежать выхода за границы видимой области. Основная задача
— корректно расположить floating element при ограниченном
пространстве, например, при появлении всплывающих подсказок, меню или
поповер-компонентов.
Ключевой момент заключается в использовании middleware
flip, которое проверяет доступное пространство
вокруг опоры и при необходимости изменяет сторону размещения.
import { computePosition, flip } from '@floating-ui/dom';
computePosition(referenceElement, floatingElement, {
middleware: [flip()]
}).then(({ x, y }) => {
Object.assign(floatingElement.style, {
left: `${x}px`,
top: `${y}px`
});
});
В этом примере flip() автоматически проверяет все четыре
направления (top, right, bottom,
left) и выбирает оптимальное, если изначально заданное
направление не помещается.
flipMiddleware flip принимает объект конфигурации с
несколькими ключевыми параметрами:
fallbackPlacements — массив альтернативных направлений, которые будут проверяться по порядку, если основное направление не подходит.
fallbackStrategy — стратегия выбора fallback-направления:
"bestFit" — выбирается вариант с наибольшим доступным
пространством."initialPlacement" — возвращается к исходной позиции,
если она частично помещается.boundary — элемент или объект, ограничивающий
пространство для всплывающего элемента. По умолчанию используется
viewport.
padding — отступ от границ
boundary, предотвращающий прилипание к краю
экрана.
Пример с кастомными fallback-направлениями:
computePosition(referenceElement, floatingElement, {
placement: 'top',
middleware: [flip({
fallbackPlacements: ['right', 'bottom', 'left'],
boundary: document.body,
padding: 8
})]
});
Здесь при невозможности разместить элемент сверху, библиотека
проверяет по очереди: справа, снизу и слева, с отступом 8 пикселей от
границ body.
flip часто используется совместно с shift и
offset для точного позиционирования:
boundary, не меняя его направления.Пример комплексного позиционирования:
computePosition(referenceElement, floatingElement, {
placement: 'bottom',
middleware: [
offset(10),
flip({ fallbackPlacements: ['top', 'right'] }),
shift({ padding: 5 })
]
});
Последовательность middleware критична: сначала определяется смещение
(offset), затем выполняется проверка переворота
(flip), а затем корректировка по границам
(shift). Такой порядок обеспечивает предсказуемое поведение
даже при ограниченном пространстве.
Иногда важно задать ограничение на количество попыток
переворота или принудительно блокировать некоторые направления.
Для этого используется сочетание flip с пользовательскими
fallbackPlacements и boundary. Например, можно
запретить всплывающему элементу появляться слева и сверху:
flip({
fallbackPlacements: ['right', 'bottom']
});
Если элемент не помещается ни в одно из разрешённых направлений, библиотека вернёт наилучшее возможное расположение, сохранив видимость максимально возможной части элемента.
Для интерактивных интерфейсов важно, чтобы элемент реагировал
на изменение размеров или прокрутку окна. Floating UI
предоставляет функцию autoUpdate, которая отслеживает
изменения и повторно вычисляет позицию:
import { autoUpdate } from '@floating-ui/dom';
autoUpdate(referenceElement, floatingElement, () => {
computePosition(referenceElement, floatingElement, {
middleware: [flip(), shift(), offset(5)]
}).then(({ x, y }) => {
Object.assign(floatingElement.style, { left: `${x}px`, top: `${y}px` });
});
});
Сочетание flip и autoUpdate гарантирует,
что даже при изменении размеров окна или движения опоры всплывающий
элемент останется видимым и корректно расположен.
Эти приёмы позволяют полностью контролировать поведение переворота, обеспечивая стабильность и адаптивность интерфейсов с плавающими элементами.