Floating UI предоставляет низкоуровневый механизм для вычисления позиции всплывающих элементов относительно их якорей. Центральная идея заключается в отделении логики вычисления позиции от визуального отображения, что позволяет создавать гибкие интерфейсы с тултипами, дропдаунами, поповерами и контекстными меню.
Библиотека работает с плавающими элементами, которые могут динамически менять свое положение в зависимости от доступного пространства, размеров окна и ограничения видимости. Основной принцип — передать библиотеке ссылку на элемент якоря и плавающий элемент, после чего она возвращает координаты для правильного позиционирования.
Основные функции библиотеки, такие как computePosition,
принимают несколько ключевых параметров:
import { computePosition, offset, flip, shift } from '@floating-ui/dom';
const reference = document.querySelector('#button');
const floating = document.querySelector('#tooltip');
computePosition(reference, floating, {
placement: 'top', // первичное направление относительно якоря
middleware: [
offset(8), // отступ от якоря
flip(), // автоматический перенос при нехватке места
shift({ padding: 5 }) // смещение в пределах видимой области
],
}).then(({ x, y }) => {
Object.assign(floating.style, {
left: `${x}px`,
top: `${y}px`
});
});
top, bottom, left,
right и их вариации с
-start/-end).placement, и при необходимости меняет направление.Middleware в Floating UI можно комбинировать для сложного позиционирования. Примеры:
import { arrow } from '@floating-ui/dom';
const arrowElement = document.querySelector('#arrow');
computePosition(reference, floating, {
placement: 'top',
middleware: [offset(10), flip(), shift({ padding: 5 }), arrow({ element: arrowElement })]
});
Arrow возвращает координаты x и y, которые
нужно применить к стрелке:
Object.assign(arrowElement.style, {
left: `${arrowData.x}px`,
top: `${arrowData.y}px`
});
Для интерфейсов с изменяющимся содержимым важно обновлять
позицию в реальном времени. Floating UI предоставляет функцию
autoUpdate, которая отслеживает изменения размеров и
прокрутки:
import { autoUpdate } from '@floating-ui/dom';
const cleanup = autoUpdate(reference, floating, () => {
computePosition(reference, floating, {
placement: 'bottom',
middleware: [offset(5), flip(), shift()]
}).then(({ x, y }) => {
Object.assign(floating.style, { left: `${x}px`, top: `${y}px` });
});
});
// остановка наблюдения
// cleanup();
autoUpdate учитывает:
Floating UI возвращает абсолютные координаты (x,
y) относительно документа. Для точного отображения важно
учитывать position CSS плавающего элемента:
position: absolute — координаты применяются
относительно ближайшего родителя с position: relative.position: fixed — координаты привязаны к окну
просмотра.С помощью middleware shift можно гарантировать, что
элемент не выйдет за пределы окна или родителя с ограничениями
видимости.
Floating UI хорошо интегрируется с React, Vue или Svelte, так как обеспечивает чистые данные о позиции, которые можно использовать в любом рендере. Пример с React:
import { useFloating, offset, flip, shift } from '@floating-ui/react';
function Tooltip({ referenceRef, children }) {
const { x, y, reference, floating, strategy } = useFloating({
middleware: [offset(10), flip(), shift()],
placement: 'top'
});
return (
<div ref={floating} style={{ position: strategy, top: y ?? 0, left: x ?? 0 }}>
{children}
</div>
);
}
Ключевые моменты:
strategy возвращает absolute или
fixed.x и y — вычисленные координаты, которые
можно применить к стилям.arrow.autoUpdate для
корректного позиционирования при изменении DOM.Floating UI строит позиционирование на математических расчетах, что обеспечивает точность и гибкость для любых сценариев — от простых тултипов до сложных кастомных дропдаунов и модальных окон.