Floating UI предоставляет мощные инструменты для позиционирования всплывающих элементов (popper, tooltip, dropdown) относительно целевых элементов. Одним из ключевых аспектов является управление положением таких элементов с учётом границ видимой области — вьюпорта. Ограничения вьюпорта позволяют предотвратить выход всплывающих элементов за пределы экрана, обеспечивая удобство и корректное отображение интерфейса.
Вьюпорт в контексте Floating UI — это область, внутри которой пользователь видит содержимое страницы без прокрутки. Обычно это размер окна браузера, но можно использовать кастомные контейнеры с прокруткой (scrollable parents).
Floating UI использует концепцию middleware, чтобы управлять позиционированием элементов. Для ограничения элементов в пределах вьюпорта применяются следующие middleware:
flipshiftautoPlacementoffset (частично, для управления расстоянием от
границ)detectOverflow (низкоуровневый инструмент для расчёта
переполнения)flipflip автоматически изменяет сторону, на которой
располагается всплывающий элемент, если он выходит за границы вьюпорта.
Пример использования:
import {computePosition, flip} from '@floating-ui/dom';
computePosition(referenceElement, floatingElement, {
placement: 'bottom',
middleware: [flip({fallbackPlacements: ['top', 'right', 'left']})],
}).then(({x, y}) => {
Object.assign(floatingElement.style, {
left: `${x}px`,
top: `${y}px`,
});
});
Ключевые моменты flip:
fallbackPlacements задаёт последовательность
альтернативных позиций, если основной вариант не помещается.detectOverflow).shift, чтобы дополнительно
смещать элемент внутрь видимой области.shiftshift отвечает за корректировку положения элемента, если
он частично выходит за границы вьюпорта. В отличие от flip,
он не меняет сторону размещения, а смещает элемент внутрь видимой
области:
import {shift} from '@floating-ui/dom';
computePosition(referenceElement, floatingElement, {
placement: 'bottom-start',
middleware: [shift({padding: 8})],
}).then(({x, y}) => {
Object.assign(floatingElement.style, {
left: `${x}px`,
top: `${y}px`,
});
});
Особенности shift:
padding задаёт минимальное расстояние до границ
вьюпорта.flip, обеспечивая корректное
позиционирование даже при смене стороны.autoPlacementautoPlacement объединяет возможности flip и
shift, предоставляя комплексное решение для динамического
выбора позиции:
import {autoPlacement} from '@floating-ui/dom';
computePosition(referenceElement, floatingElement, {
middleware: [
autoPlacement({
alignment: 'start',
allowedPlacements: ['top', 'bottom', 'right', 'left'],
padding: 10
})
],
}).then(({x, y, placement}) => {
Object.assign(floatingElement.style, {
left: `${x}px`,
top: `${y}px`,
});
});
Преимущества autoPlacement:
allowedPlacements.shift) при
необходимости.detectOverflowdetectOverflow предоставляет точные данные о том,
насколько элемент выходит за пределы контейнера или вьюпорта. Его можно
использовать для кастомной логики позиционирования:
import {detectOverflow} from '@floating-ui/dom';
const overflow = await detectOverflow(floatingElement, {boundary: document.documentElement});
console.log(overflow); // {top: 0, bottom: 50, left: 0, right: 20}
Важные детали:
boundary.Floating UI позволяет задавать кастомные контейнеры для ограничения элементов:
computePosition(referenceElement, floatingElement, {
middleware: [shift({boundary: document.querySelector('#scrollable-container')})]
});
Параметр boundary может быть:
viewport (по умолчанию)В сочетании с padding позволяет тонко управлять
расстоянием до краёв контейнера.
flip + shift, чтобы
элемент корректно менял сторону и оставался внутри видимой области.autoPlacement упрощает логику для сложных интерфейсов,
особенно с элементами разной высоты или ширины.boundary, иначе элемент может выходить за пределы
контейнера.padding и offset для того, чтобы элемент не
прилипал к краям и оставался читаемым.Использование middleware flip, shift и
autoPlacement вместе с detectOverflow
позволяет создавать гибкие и адаптивные интерфейсы. Ограничение
всплывающих элементов границами вьюпорта делает интерфейс безопасным и
предотвращает обрезание контента. Floating UI предоставляет точный и
настраиваемый механизм управления переполнением, который подходит для
всех типов всплывающих элементов.