Функция computePosition является ядром библиотеки
Floating UI и отвечает за вычисление точного положения
плавающих элементов относительно их целевых якорей (reference elements).
Она возвращает координаты x и y для
абсолютного позиционирования элемента, а также дополнительные данные,
которые позволяют гибко управлять поведением попапов, тултипов,
dropdown-меню и других интерфейсных компонентов.
import { computePosition } from '@floating-ui/dom';
const reference = document.querySelector('#button');
const floating = document.querySelector('#tooltip');
computePosition(reference, floating, {
placement: 'top'
}).then(({ x, y }) => {
Object.assign(floating.style, {
left: `${x}px`,
top: `${y}px`
});
});
В этом примере computePosition рассчитывает координаты
всплывающего элемента так, чтобы он оказался над
кнопкой (placement: 'top').
reference и
floatingreference — DOM-элемент или объект,
представляющий привязку (anchor).floating — DOM-элемент, который
позиционируется.computePosition принимает третий аргумент — объект с
параметрами конфигурации:
'top' | 'bottom' | 'left' | 'right' с возможными вариантами
'-start' и '-end'.'absolute' | 'fixed' —
определяет стратегию позиционирования.Middleware — это функции, которые расширяют возможности позиционирования, корректируют координаты и управляют видимостью элемента.
import { offset } from '@floating-ui/dom';
computePosition(reference, floating, {
placement: 'bottom',
middleware: [offset(10)]
});
Элемент будет смещён на 10 пикселей вниз.
import { flip } from '@floating-ui/dom';
computePosition(reference, floating, {
placement: 'top',
middleware: [flip()]
});
Если сверху нет места, тултип автоматически перейдёт вниз.
import { shift } from '@floating-ui/dom';
computePosition(reference, floating, {
placement: 'left',
middleware: [shift({ padding: 5 })]
});
Сдвиг происходит с учётом padding, предотвращая
обрезание.
import { arrow } from '@floating-ui/dom';
const arrowElement = document.querySelector('#arrow');
computePosition(reference, floating, {
placement: 'top',
middleware: [arrow({ element: arrowElement })]
});
Возвращает объект x и y для корректного
позиционирования стрелки.
computePosition возвращает Promise, что
позволяет использовать async/await для упрощения кода:
async function updatePosition() {
const { x, y, placement } = await computePosition(reference, floating, {
placement: 'bottom',
middleware: [offset(5), flip(), shift()]
});
Object.assign(floating.style, {
left: `${x}px`,
top: `${y}px`
});
}
Асинхронность особенно важна при работе с динамическими элементами или при расчёте позиций внутри сложных контейнеров.
Объект, который возвращает computePosition,
содержит:
{
x: 100,
y: 50,
placement: 'top',
middlewareData: {
arrow: { x: 10, y: 0 },
shift: { x: 5, y: 0 }
}
}
position: relative или
absolute.computePosition(reference, floating, {
strategy: 'fixed',
placement: 'right'
});
Используется для модальных окон и тултипов, которые должны оставаться на месте при скролле страницы.
Middleware можно комбинировать для достижения сложного поведения:
computePosition(reference, floating, {
placement: 'top-start',
middleware: [
offset(8),
flip({ fallbackPlacements: ['bottom-start', 'bottom-end'] }),
shift({ padding: 10 }),
arrow({ element: arrowElement })
]
});
Порядок имеет значение: offset применяется первым,
flip — вторым, и так далее. Это позволяет точно
контролировать результат.
flip и shift для
адаптивного позиционирования.arrow, а координаты
брать из middlewareData.arrow.fixed.computePosition предоставляет полный контроль над
позиционированием интерфейсных элементов, объединяя простоту API с
мощной системой middleware для сложных сценариев.