Floating UI — это библиотека для управления позиционированием плавающих элементов в веб-интерфейсах, таких как тултипы, всплывающие меню, поповеры и модальные окна. Основная задача библиотеки — обеспечивать динамическое и точное расположение элементов относительно целевых объектов с учётом ограничений viewport, границ контейнера и коллизий.
Для начала работы используется функция
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(10), flip(), shift({ padding: 5 })],
}).then(({ x, y }) => {
Object.assign(floating.style, {
left: `${x}px`,
top: `${y}px`
});
});
Ключевые моменты:
reference — целевой элемент, относительно которого
позиционируется всплывающее окно.floating — элемент, который нужно разместить.placement — базовое расположение: 'top',
'bottom', 'left', 'right' и их
варианты с -start или -end.middleware — массив функций, которые изменяют позицию с
учётом разных условий.Middleware — это модификаторы поведения плавающего элемента. Они позволяют контролировать смещение, предотвращать выход за границы, переворачивать позицию и добавлять динамические сдвиги.
Добавляет смещение плавающего элемента относительно целевого:
offset(10) // смещение на 10px
Можно использовать функцию для динамического смещения:
offset(({ placement }) => (placement === 'top' ? 20 : 5))
Автоматически переворачивает элемент, если выбранная сторона выходит за пределы видимой области:
flip({
fallbackPlacements: ['bottom', 'right']
})
Особенности:
fallbackPlacements — список альтернативных
позиций.shift для корректной адаптации
в ограниченном пространстве.Сдвигает элемент внутри видимой области, чтобы он не выходил за границы контейнера:
shift({ padding: 8 })
Ключевой параметр — padding, задающий
минимальное расстояние до границ.
Позволяет размещать стрелку на всплывающем элементе, указывающую на целевой элемент:
import { arrow } from '@floating-ui/dom';
arrow({ element: document.querySelector('.arrow') })
Возвращает координаты x и y для корректного
позиционирования стрелки.
Floating UI поддерживает два типа стратегий:
absolute — позиционирование
относительно ближайшего позиционированного родителя.fixed — фиксированное позиционирование
относительно viewport.Выбор стратегии осуществляется через опцию strategy:
computePosition(reference, floating, {
strategy: 'fixed',
});
Floating UI может автоматически учитывать размеры элементов и границы контейнера с помощью middleware:
import { autoUpdate } from '@floating-ui/dom';
const cleanup = autoUpdate(reference, floating, () => {
computePosition(reference, floating, { middleware: [offset(5), flip(), shift()] }).then(({ x, y }) => {
Object.assign(floating.style, { left: `${x}px`, top: `${y}px` });
});
});
Комбинирование offset, flip,
shift и arrow позволяет создавать сложные
интерактивные элементы:
computePosition(reference, floating, {
placement: 'top',
middleware: [
offset(10),
flip({ fallbackPlacements: ['bottom', 'right'] }),
shift({ padding: 5 }),
arrow({ element: document.querySelector('.arrow') })
]
});
Особенности:
x, y, placement и
strategy.Floating UI позволяет создавать собственные middleware:
function customMiddleware() {
return {
name: 'custom',
async fn({ x, y }) {
return { x: x + 5, y: y + 5 };
}
};
}
Middleware могут быть асинхронными, что полезно при динамическом расчёте позиций на основе API или DOM.
Для React и других фреймворков есть специализированные хуки, например
useFloating, которые упрощают интеграцию с компонентами и
автоматически обрабатывают обновления позиции при изменениях DOM.
Если нужно, я могу подготовить отдельную секцию с полным списком всех middleware и их опциями, с подробными примерами каждого — это будет идеальный справочник для учебника.
Хочешь, чтобы я сделал такую секцию?