Floating UI — это библиотека для JavaScript, предназначенная для создания динамических позиционированных элементов интерфейса, таких как всплывающие подсказки, контекстные меню, дропдауны и модальные окна. Она обеспечивает точное и предсказуемое размещение элементов относительно других элементов на странице с учетом различных условий, включая прокрутку, размеры окна и препятствия в виде других элементов.
Главная задача Floating UI — отделить логику позиционирования от визуального отображения, предоставляя программисту мощный API для управления позиционированием.
В Floating UI выделяются два ключевых элемента:
Эти два элемента связываются через позиционирующий механизм, который вычисляет оптимальные координаты.
Floating UI предоставляет функции для вычисления позиции:
import { computePosition } from '@floating-ui/dom';
computePosition(referenceElement, floatingElement, {
placement: 'bottom-start',
middleware: [
offset(10),
flip(),
shift({ padding: 5 })
]
}).then(({ x, y }) => {
Object.assign(floatingElement.style, {
left: `${x}px`,
top: `${y}px`
});
});
placement — определяет предпочтительное расположение (top, bottom, left, right и их вариации).
middleware — набор функций, которые изменяют поведение позиционирования:
offset — смещение от reference;flip — позволяет элементу переворачиваться, если не
помещается;shift — корректирует позицию для предотвращения выхода
за пределы видимой области.Middleware — ключевая особенность Floating UI. Каждая функция middleware принимает исходные координаты и возвращает новые. Примеры:
flip() Перемещает floating элемент на противоположную сторону, если исходное место не помещается в viewport.
shift({ padding }) Сдвигает элемент внутрь видимой области с заданным отступом.
size() Автоматически подстраивает размеры floating элемента под доступное пространство.
arrow({ element }) Создает динамическую стрелку, указывающую на reference элемент.
Middleware можно комбинировать для сложных сценариев:
middleware: [
offset(8),
flip(),
shift({ padding: 5 }),
arrow({ element: arrowElement })
]
Floating UI поддерживает обновление позиции в режиме реального времени при изменении размеров окна, скролле или изменении содержимого:
import { autoUpdate } from '@floating-ui/dom';
const cleanup = autoUpdate(referenceElement, floatingElement, () => {
computePosition(referenceElement, floatingElement, { placement: 'bottom' })
.then(({ x, y }) => {
Object.assign(floatingElement.style, { left: `${x}px`, top: `${y}px` });
});
});
// Для остановки отслеживания изменений
cleanup();
autoUpdate следит за всеми необходимыми событиями и
автоматически пересчитывает координаты, обеспечивая корректное поведение
при динамическом изменении интерфейса.
Floating UI не управляет отображением самих элементов, но предоставляет точную информацию о положении, что позволяет легко реализовать интерактивные сценарии. Например:
referenceElement.addEventListener('mouseenter', () => {
floatingElement.style.display = 'block';
computePosition(referenceElement, floatingElement, { placement: 'top' });
});
referenceElement.addEventListener('mouseleave', () => {
floatingElement.style.display = 'none';
});
Библиотека разделена на два основных пакета:
В React можно использовать хук useFloating:
import { useFloating, offset, flip } from '@floating-ui/react';
const { x, y, reference, floating } = useFloating({
placement: 'bottom',
middleware: [offset(10), flip()]
});
reference и floating используются как
ref для элементов React, обеспечивая автоматическое
позиционирование без ручного доступа к DOM.
Floating UI становится особенно полезной при разработке интерфейсов, где важна точная позиция элементов и их адаптация к изменяющемуся окружению, без необходимости вручную рассчитывать координаты и обрабатывать все edge-case сценарии.