Floating UI предоставляет гибкий механизм для позиционирования всплывающих элементов, таких как тултипы, всплывающие меню, поповеры и модальные окна, с учётом доступного пространства вокруг целевого элемента. Ключевым аспектом является обеспечение того, чтобы всплывающий элемент не выходил за пределы видимой области экрана или контейнера, сохраняя при этом удобство взаимодействия.
Floating UI использует концепцию overflow boundaries — границ, за которыми элемент не должен выходить. Эти границы могут быть:
viewport) Используется для предотвращения выхода
элемента за пределы экрана.clipping ancestor)
Позволяет ограничивать позицию всплывающего элемента рамками
родительского блока с overflow: hidden, scroll
или auto.Для задания границ применяется опция middleware, где
можно использовать встроенные функции, такие как flip,
shift и size.
Мидлвар flip отвечает за изменение стороны появления
всплывающего элемента при недостатке пространства. Пример
использования:
import { computePosition, flip } from '@floating-ui/dom';
const reference = document.querySelector('#button');
const floating = document.querySelector('#tooltip');
computePosition(reference, floating, {
placement: 'bottom',
middleware: [flip()],
}).then(({ x, y }) => {
Object.assign(floating.style, {
left: `${x}px`,
top: `${y}px`,
});
});
Особенности flip:
flip({ fallbackPlacements: ['top', 'right', 'left'] });
Мидлвар shift обеспечивает смещение всплывающего
элемента так, чтобы он полностью помещался в доступное пространство, не
выходя за границы.
import { shift } from '@floating-ui/dom';
computePosition(reference, floating, {
placement: 'bottom',
middleware: [shift({ padding: 8 })], // отступ от границ
});
Параметры:
padding — минимальное расстояние от границ.flip для более гибкого
поведения.Мидлвар size позволяет динамически изменять размеры
всплывающего элемента в зависимости от доступного пространства:
import { size } from '@floating-ui/dom';
computePosition(reference, floating, {
placement: 'bottom',
middleware: [
size({
apply({ availableWidth, availableHeight, elements }) {
Object.assign(elements.floating.style, {
maxWidth: `${availableWidth}px`,
maxHeight: `${availableHeight}px`,
});
},
}),
],
});
Принципы работы:
flip и shift,
создавая полноценное адаптивное позиционирование.Для полноценного управления пространством рекомендуется использовать цепочку мидлваров. Порядок имеет значение:
computePosition(reference, floating, {
placement: 'bottom-start',
middleware: [
flip({ fallbackPlacements: ['top-start', 'right-start'] }),
shift({ padding: 10 }),
size({
apply({ availableWidth, elements }) {
elements.floating.style.maxWidth = `${availableWidth}px`;
},
}),
],
});
Пояснения:
Floating UI поддерживает функцию autoUpdate, которая автоматически пересчитывает позицию при изменении размеров окна, скролле или изменении размеров элемента:
import { autoUpdate } from '@floating-ui/dom';
autoUpdate(reference, floating, () => {
computePosition(reference, floating, {
placement: 'bottom',
middleware: [flip(), shift({ padding: 8 })],
}).then(({ x, y }) => {
Object.assign(floating.style, { left: `${x}px`, top: `${y}px` });
});
});
Таким образом, всплывающий элемент остаётся корректно позиционированным в любой ситуации.
flip для предотвращения выхода за границы
при фиксированном направлении.shift для смещения элементов внутри доступной
области.size для адаптивной подгонки
размеров.autoUpdate, если элемент должен реагировать
на динамические изменения страницы.Эти механизмы позволяют создавать гибкие, адаптивные всплывающие элементы, полностью учитывающие ограниченные пространства и улучшая пользовательский опыт.