Библиотека Floating UI в JavaScript предоставляет мощные инструменты для динамического позиционирования элементов интерфейса, таких как всплывающие окна, тултипы и меню. В дополнение к автоматическим алгоритмам позиционирования, Floating UI позволяет полностью контролировать координаты элементов вручную, что особенно полезно при сложных пользовательских интерфейсах или нестандартных требованиях к расположению.
Ручное управление позицией достигается через использование
функции computePosition с последующей
обработкой результатов для явного задания стиля элемента.
import { computePosition } from '@floating-ui/dom';
const reference = document.querySelector('#button');
const floating = document.querySelector('#tooltip');
computePosition(reference, floating, {
placement: 'bottom',
}).then(({ x, y }) => {
Object.assign(floating.style, {
left: `${x}px`,
top: `${y}px`,
position: 'absolute',
});
});
Ключевой момент: computePosition
возвращает объект с координатами x и y,
которые можно использовать напрямую для установки
style.left и style.top. Это дает полный
контроль над положением элемента без необходимости полагаться на
встроенные middleware для смещения или предотвращения выхода за
границы.
Ручное позиционирование не ограничивается простым отображением на
координатах x и y. Floating UI поддерживает
middleware, которые могут быть применены даже при
ручном управлении для тонкой настройки позиции:
import { offset, flip } from '@floating-ui/dom';
computePosition(reference, floating, {
placement: 'right',
middleware: [offset(10), flip()],
}).then(({ x, y, placement }) => {
Object.assign(floating.style, {
left: `${x}px`,
top: `${y}px`,
position: 'absolute',
});
floating.dataset.placement = placement;
});
offset(value) позволяет добавить смещение от исходной
позиции.flip() динамически меняет сторону, если элемент не
помещается в видимую область.Даже при ручном управлении middleware остаются полезным инструментом для точной кастомизации поведения позиционирования, сохраняя контроль над стилями.
Ручное управление особенно важно, когда элемент должен следовать за движением reference-элемента или анимироваться. В таких случаях используется цикл обновления позиции:
function updatePosition() {
computePosition(reference, floating).then(({ x, y }) => {
Object.assign(floating.style, {
left: `${x}px`,
top: `${y}px`,
position: 'absolute',
});
requestAnimationFrame(updatePosition);
});
}
updatePosition();
Особенности:
requestAnimationFrame позволяет обновлять
позицию плавно при изменении положения reference-элемента.Для элементов, которые не должны выходить за границы окна, можно вручную корректировать координаты после получения позиции:
computePosition(reference, floating).then(({ x, y }) => {
const boundedX = Math.max(0, Math.min(x, window.innerWidth - floating.offsetWidth));
const boundedY = Math.max(0, Math.min(y, window.innerHeight - floating.offsetHeight));
Object.assign(floating.style, {
left: `${boundedX}px`,
top: `${boundedY}px`,
position: 'absolute',
});
});
Принцип: ручное ограничение координат позволяет
гибко контролировать положение без необходимости полагаться на
middleware shift(). Это важно, когда требуется
специфическая логика адаптивности или при работе с нестандартными
контейнерами.
Ручное позиционирование легко комбинируется с событиями интерфейса:
document.addEventListener('mousemove', (event) => {
const x = event.clientX + 10;
const y = event.clientY + 10;
Object.assign(floating.style, {
left: `${x}px`,
top: `${y}px`,
position: 'absolute',
});
});
Floating UI позволяет учитывать размеры reference-элемента и самого
floating-элемента, что критично при ручном управлении. Для динамического
контента можно использовать ResizeObserver:
const resizeObserver = new ResizeObserver(() => {
computePosition(reference, floating).then(({ x, y }) => {
Object.assign(floating.style, { left: `${x}px`, top: `${y}px` });
});
});
resizeObserver.observe(reference);
resizeObserver.observe(floating);
Преимущества:
computePosition для расчета
базовых координат.Ручное управление позицией позволяет полностью контролировать отображение элементов, при этом сохраняя возможности Floating UI по точному и безопасному вычислению координат в любых условиях.